programing

SQL Server에서 CREATE 또는 ALTER를 수행할 작업은 무엇입니까?

testmans 2023. 6. 29. 19:54
반응형

SQL Server에서 CREATE 또는 ALTER를 수행할 작업은 무엇입니까?

2009년이며 SQL Server에는 CREATE 또는 ALTER/REPLACE가 없습니다.대신에 제가 하는 일은 이렇습니다.

IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.ROUTINES 
           WHERE ROUTINE_NAME = 'SynchronizeRemoteCatalog' 
             AND ROUTINE_SCHEMA = 'dbo' 
             AND ROUTINE_TYPE = 'PROCEDURE')
 EXEC ('DROP PROCEDURE dbo.SynchronizeRemoteCatalog')

CREATE PROCEDURE dbo.SynchronizeRemoteCatalog
AS BEGIN
    -- body
END

트리거의 경우 전용 시스템 뷰에 의존해야 합니다.

이것이 그 동안 가장 받아들여진 컨벤션입니까?

편집: n8wrl이 제안한 것처럼 공식 단어는 이 기능이 우선 순위가 높지 않음을 시사합니다.그렇기 때문에 질문입니다.

이 문서는 SQL 서버에서 개체를 삭제할 때 사용 권한을 잃는 것에 대해 잘 설명합니다.

다음은 권한을 유지하는 접근 방식입니다.

IF OBJECT_ID('spCallSomething') IS NULL
    EXEC('CREATE PROCEDURE spCallSomething AS SET NOCOUNT ON;')
GO

ALTER PROCEDURE spCallSomething ... 
--instead of DROP/CREATE

기능에도 사용할 수 있습니다. 교체하십시오.PROCEDURE와 함께FUNCTION상기 코드로

이런 식으로 하는 것을 고려해야 하는 또 다른 이유는 실패에 대한 내성입니다.Drop은 성공하지만 CREATE는 실패하고 DB가 손상된 상태로 끝난다고 가정합니다.ALTER 접근 방식을 사용하면 이전 버전의 개체를 사용하게 됩니다.

2009년이며 SQL Server에는 CREATE 또는 ALTER/REPLACE가 없습니다.

2016년에는 SQL Server 2016 RTM에 DRIE(Drop If Exists)가 있습니다.CREATE OR ALTER SP1 ). 2016년 SP1 출시)

내는꺼를 하는 중Drop If Exists먼저 이 접근 방식을 사용하여 권한을 다시 할당해야 하는 경우의 주의 사항이 여전히 적용됩니다.구문의 예는 다음과 같습니다.

DROP PROCEDURE IF EXISTS dbo.SynchronizeRemoteCatalog

GO

CREATE PROCEDURE dbo.SynchronizeRemoteCatalog
AS
  BEGIN
      BODY:
  END 

GO

/*TODO: Reapply permissions*/

CREATE OR ALTER사용 권한을 유지합니다.구문의 예는 다음과 같습니다.

 CREATE OR ALTER PROCEDURE dbo.SynchronizeRemoteCatalog
 AS
 BEGIN
   BODY:
 END

해당 MSSQL Tiger Team 블로그 게시물에서 설명합니다.

CREATE OR ALTER는 다음과 같은 프로그래밍 가능성 객체에 사용할 수 있습니다.

  • 저장 프로시저(기본적으로 컴파일된 프로시저 포함)
  • FUNCTION(기본적으로 컴파일된 Transact-SQL 포함)
  • 트리거
  • 보기

그러나 다음에서 사용할 수 없습니다.

  • 스토리지가 필요한 개체(테이블, 인덱스 및 인덱스 보기)
  • CLR 사용자 정의 함수
  • 사용되지 않는 프로그래밍 가능성 개체(RULE 및 DEFAULT)
  • 프로그래밍 불가능 개체(예: CREATE ASEMBLE, CREATE TABLE 또는 CREATE - SCHEMA).이러한 개체에서 CREATE 및 ALTER의 구문은 구문 및 사용성 관점과 매우 다릅니다.

원격 사이트를 업데이트해야 하지만 DROP 권한이 없는 상황이 발생했습니다.지금까지는 SSMS 2008 R2에 내장된 'DROP and CREATE' 스크립트를 사용했지만 이제는 변경해야 했습니다.저장 프로시저 또는 기능을 업데이트해야 할 때 적절한 ALTER 스크립트 위에 놓는 세 가지 템플릿을 만들었습니다.

—- Stored Procedure
IF OBJECT_ID('[dbo].[<Name_Of_Routine, , >]') IS NULL
EXEC('CREATE PROCEDURE [dbo].[<Name_Of_Routine, , >] AS SET NOCOUNT ON;')
EXEC('GRANT EXECUTE ON [<Name_Of_Routine, , >] TO Public AS dbo;')
GO

—- Scalar Function
IF OBJECT_ID('[dbo].[<Name_Of_Routine, , >]') IS NULL
EXEC('CREATE FUNCTION [dbo].[<Name_Of_Routine, , >] (@i INT) RETURNS INT AS BEGIN RETURN 0 END;')
EXEC('GRANT EXECUTE ON [<Name_Of_Routine, , >] TO Public AS dbo;')
GO

—- Table-based Function
IF OBJECT_ID('[dbo].[<Name_Of_Routine, , >]') IS NULL
EXEC('CREATE FUNCTION [dbo].[<Name_Of_Routine, , >] (@i INT) RETURNS @O TABLE(i INT) AS BEGIN INSERT INTO @O SELECT 0 RETURN END;')
GO

각 CREATE 후 특수 권한이 스크립트로 작성됩니다(테이블 함수에는 권한을 할당할 수 없음).그 후 ALTER는 변경하지 않으며 권한을 추가하거나 수정하면 변경되지 않습니다.이렇게 하면 함수 또는 저장 프로시저의 이름을 복사하고 템플릿 매개 변수 대체를 사용하여 이러한 스크립트let의 완료를 자동화하는 것이 쉬운 작업입니다.

이제, 저는 마이크로소프트의 좋은 사람들이 이것을 그들의 "스크립트__as" 목록에 추가하거나 이 스크립트가 '베이킹 인'이 되도록 우리만의 것을 만들 수 있는 기능을 제공하기를 바랍니다.

https://connect.microsoft.com/SQLServer/feedback/details/344991/create-or-alter-statement 의 SQL Server 피드백 항목 뒤에 무게를 두는 것이 좋습니다.아직 공개적으로 접근할 수 있는 몇 안 되는 것으로 보이며, "조만간 이것을 선적할 수 있을지 결정하기 위해 이것에 대한 타당성 검토를 시작했다"고 밝혔습니다.더 많은 목소리를 낼수록, 이런 일이 일어날 가능성이 더 높습니다!

(Update: 이제 트리거 및 보기에도 다음 코드를 사용합니다.)

-- Triggers
IF OBJECT_ID('[dbo].[<Name_Of_Trigger, , >]') IS NULL -- Check if Trigger Exists
    EXEC('CREATE TRIGGER [dbo].[<Name_Of_Trigger, , >] ON [<Name_Of_Table, , >] AFTER UPDATE AS SET NOCOUNT ON;') -- Create dummy/empty SP
GO

-- Views
IF OBJECT_ID('[dbo].[<Name_Of_View, , >]') IS NULL -- Check if View Exists
    EXEC('CREATE VIEW [dbo].[<Name_Of_View, , >] AS SELECT 1;') -- Create dummy/empty View
GO

개발자가 작성할 때마다IF EXISTS(...) DROP물개가 몽둥이가 되다데이터베이스에 있는 내용을 정확히 알고 있어야 하며 업그레이드 스크립트는 응용프로그램 스키마의 현재 버전에 따라 CREATE 또는 ALTER를 적절하게 수행해야 합니다.버전 제어데이터베이스.

제가 쓰겠습니다.OBJECT_ID(...) IS NOT NULL물방울이 떨어지기 전에

개체 식별자는 고유해야 하므로 시스템 테이블을 사용하지 않고 작동합니다.

CREATE TRIGGER dbo.ExistingTable ON dbo.AnotherTable FOR UPDATE
AS 
SET NOCOUNT ON
GO

기브즈

Msg 2714, Level 16, State 2, Procedure MetaClass, Line 3
There is already an object named ExistingTable ' in the database.

저는 소스 제어 등으로 작업하는 방식 때문에 ALTER를 주로 사용합니다.

는 항상 나는항상.alter나의 목적은 a 때문입니다.drop개체가 생성되지 않을 경우(24/7 db!), 다른 포스터에서 핵 사용 권한에 대해 언급한 내용을 포함하여 DB가 잘못된 상태로 유지될 수 있습니다.

Sublime 및 생성할 수 합니다. Sublime, Atom 및 VS Code를 지원합니다.DROP IF EXISTS - 이 구하지만여방잘접향서다근니에합것 - 이모든전성못히된▁construct것▁-.drop/createcreate alter또한했습니다. 저는 머리글보다 더 . 그래서 저는 더 이상 화려하지 않습니다.create proc dbo.myproc as▁the로서create뭉툭한

보기:

if objectproperty(object_id('dbo.myview'), 'IsView') is null begin
    exec('create view dbo.myview as select 1 c')
end
go
alter view dbo.myview as
    -- select *
    -- from table
go

프로시저:

if objectproperty(object_id('dbo.myproc'), 'IsProcedure') is null begin
    exec('create proc dbo.myproc as')
end
go
alter procedure dbo.myproc as
    set nocount on
    -- Add the stored proc contents here...
go

UDF(스칼라):

if objectproperty(object_id('dbo.myudf'), 'IsScalarFunction') is null begin
    exec('create function dbo.myudf returns int as begin return null end')
end
go
alter function dbo.myudf(@s varchar(100)) returns int as
begin
    -- return len(@s)
end
go

UDF(표):

if objectproperty(object_id('dbo.myudf'), 'IsTableFunction') is null begin
    exec('create function dbo.myudf returns @t table(x int) as begin return end')
end
go
alter function dbo.myudf(@s varchar(100))
    returns @result table (
        -- Columns returned by the function
        id int identity(1, 1) primary key not null
        ,result varchar(100) null
    )
begin
    return
end
go

그게 기본적으로 그렇게 하는 방법입니다."EXEC" 접근 방식을 사용해야 하는 특별한 이유가 있는지 궁금합니다.

IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'SynchronizeRemoteCatalog' AND ROUTINE_SCHEMA = 'dbo' AND ROUTINE_TYPE = 'PROCEDURE')
    EXEC ('DROP PROCEDURE dbo.SynchronizeRemoteCatalog')

왜 그냥:

IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'SynchronizeRemoteCatalog' AND ROUTINE_SCHEMA = 'dbo' AND ROUTINE_TYPE = 'PROCEDURE')
    DROP PROCEDURE dbo.SynchronizeRemoteCatalog

???

트리거의 경우,sys.triggers이것들은 "sys" 스키마의 시스템 카탈로그 뷰입니다. 엄격하거나 직접적인 테이블은 아닙니다.

마르크

2017년이며 SQL Server에는 CREATE OR ALTER가 있습니다.

SQL Server 2016 SP1 및 SQL Server vNext에는 다음을 위한 새로운 T-SQL 언어 문 – CREATE [OR ALTER]이 있습니다.

  • 저장 프로시저
  • 기능들
  • 트리거
  • 보기

https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/11/17/create-or-alter-another-great-language-enhancement-in-sql-server-2016-sp1/

선호합니다CREATE-ALTER에대구접근(구문이 DROP-CREATE다음 두 이유 에:

  • 사사권한용DROP-CREATE재생성해야 합니다.)
  • object_id(임의의 개체가 변경하지 않음)

»DROP-CREATE:

--Initial creation:
CREATE PROCEDURE dbo.my_proc
AS
SELECT *
FROM dbo.a
WHERE i < 10;
GO

SELECT OBJECT_ID('dbo.my_proc');
GO


-- Recreating
DROP PROCEDURE IF EXISTS dbo.my_proc;
GO

CREATE PROCEDURE dbo.my_proc
AS
-- some meaningless comment
SELECT *
FROM dbo.a
WHERE i < 10;
GO

SELECT OBJECT_ID('dbo.my_proc');
GO

DB 피들

가 볼 수 다시피보.object_id변했다.

2: § 2:CREATE-ALTER

-- Initial creation
CREATE PROCEDURE dbo.my_proc2
AS
SELECT *
FROM dbo.a
WHERE i < 10;
GO

SELECT OBJECT_ID('dbo.my_proc2');
GO

-- Altering
CREATE OR ALTER PROCEDURE dbo.my_proc2
AS
-- some meaningless comment
SELECT *
FROM dbo.a
WHERE i < 10;
GO

SELECT OBJECT_ID('dbo.my_proc2');
GO

DB 피들

이 시나리오에서는object_id그대로 유지됩니다.


이로 인해 문제가 발생할 수 있는 예 시나리오.SQL Server 2016 Query Store를 사용하고 저장 프로시저에 특정 쿼리 계획을 사용한다고 가정합니다.

드롭-생성

USE T1;
GO
-- make sure that Query Store is READ_WRITE 
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[a]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[a](
    [i] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [g] [uniqueidentifier] NULL,
    [z] VARCHAR(10)
);
END
GO

-- populate table (15k records)
INSERT INTO dbo.a(g, z)
SELECT NEWID(), number
FROM (SELECT CAST([key] AS INT) AS number 
    FROM OPENJSON( '[1' + REPLICATE(',1',3000-1)+']')
    ) AS num
GO 5

-- initial creation
CREATE PROCEDURE dbo.my_proc
AS
SELECT *
FROM dbo.a
WHERE z LIKE '12%'
AND 1 = (SELECT 1);
GO

-- Clustered Index Scan
EXEC dbo.my_proc;

EXEC sp_query_store_flush_db; 

SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;
GO
--dc1

-- creating index
CREATE NONCLUSTERED INDEX IX_dbo_a_z
ON dbo.a([z] ASC) INCLUDE ([i], [g]);
GO

-- index seek
EXEC dbo.my_proc;

EXEC sp_query_store_flush_db; 

SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;

-- forcing plan GUI, clustered scan
-- dc3

EXEC sp_query_store_flush_db; 
SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;
-- dc4

-- Clustered Index Scan
EXEC dbo.my_proc;

EXEC sp_query_store_flush_db; 
SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;
-- dc5

/* MAIN PART  - DROP - RECREATE */
DROP PROCEDURE IF EXISTS dbo.my_proc;
GO

CREATE PROCEDURE dbo.my_proc
AS
-- some meaningless comment added by developer
SELECT *
FROM dbo.a
WHERE z LIKE '12%'
AND 1 = (SELECT 1);
GO

/* MAIN PART END */

-- Index Seek
EXEC dbo.my_proc;

EXEC sp_query_store_flush_db; 
SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;
-- object_id in query store is NULL
-- is_forced_plan flag is ignored !!!  

번째 실행 번째실행첫:
DC1

인덱스 추가 및 실행:

강제 계획:

다른 실행:

나 뒤에DROP-CREATE: enter image description here


작성 - 변경

USE T2;
GO
-- make sure that Query Store is READ_WRITE 
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[a]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[a](
    [i] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [g] [uniqueidentifier] NULL,
    [z] VARCHAR(10)
);
END
GO

-- populate table (15k records)
INSERT INTO dbo.a(g, z)
SELECT NEWID(), number
FROM (SELECT CAST([key] AS INT) AS number 
    FROM OPENJSON( '[1' + REPLICATE(',1',3000-1)+']')
    ) AS num
GO 5

-- initial creation
CREATE PROCEDURE dbo.my_proc
AS
SELECT *
FROM dbo.a
WHERE z LIKE '12%'
AND 1 = (SELECT 1);
GO

-- Clustered Index Scan
EXEC dbo.my_proc;

EXEC sp_query_store_flush_db; 
SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;
-- ca1
GO

-- creating index
CREATE NONCLUSTERED INDEX IX_dbo_a_z
ON dbo.a([z] ASC) INCLUDE ([i], [g]);
GO

-- index seek
EXEC dbo.my_proc;

EXEC sp_query_store_flush_db; 
SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;
--ca2

-- forcing plan GUI
--ca3

EXEC sp_query_store_flush_db; 
SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;
--ca4

-- Clustered Index Scan
EXEC dbo.my_proc;

EXEC sp_query_store_flush_db; 
SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;
--ca5
GO

/* MAIN PART  - CREATE-ALTER */
CREATE OR ALTER PROCEDURE dbo.my_proc
AS
-- some meaningless comment added by developer
SELECT *
FROM dbo.a
WHERE z LIKE '12%'
AND 1 = (SELECT 1);
GO

/* MAIN PART END */

-- Clustered Index Scan
EXEC dbo.my_proc;

EXEC sp_query_store_flush_db; 
SELECT qsq.query_id,
    qsq.query_text_id,
    qsq.context_settings_id,
    qsq.[object_id],
    OBJECT_NAME(qsq.[object_id]) AS [object_name],
    qsp.is_forced_plan,
    qsqt.query_sql_text,
    qsrs.count_executions,
    CAST(qsp.query_plan AS XbML) AS sql_query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_query_text qsqt
ON qsq.query_text_id = qsqt.query_text_id
JOIN sys.query_store_plan qsp
ON qsq.query_id= qsp.query_id
JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
WHERE query_sql_text LIKE '%dbo.a%'
AND qsq.[object_id] <> 0
ORDER BY qsq.query_id;

-- is_forced_plan is valid

번째 실행 번째실행첫:
enter image description here

인덱스 추가 및 실행:

강제 계획:

다른 실행:

나 뒤에CREATE-ALTER: enter image description here

결과

Drop-Create를 사용하면 강제 계획을 잃게 됩니다.

잠시 중단된 것 같습니다. 링크 텍스트

나를 위한 일반적인 스크립트:

IF EXISTS (SELECT name FROM sysobjects WHERE name = 'ig_InsertDealer' AND type = 'P')
    DROP PROC dbo.ig_InsertDealer
GO 
CREATE PROCEDURE dbo.ig_InsertDealer
...
GO
GRANT EXECUTE ON dbo.ig_InsertDealer TO ...
GO

상황에 따라 사용할 것입니다. 초기 빌드 또는 주요 리팩토링 스크립트는 check/drop/create, 순수 유지보수 스크립트는 alternate를 사용합니다.

오류 없이 스크립트를 여러 번 실행할 수 있는 템플릿이 있습니다.

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[aaa_test]') AND type in (N'P', N'PC'))
    EXEC('CREATE PROCEDURE aaa_test AS')
    EXEC('GRANT EXECUTE ON aaa_test TO someone')
GO

ALTER PROCEDURE aaa_test 
     @PAR1 INT,
     @PAR2 INT=0
AS
BEGIN
    SELECT @PAR1 AS Par1, CASE @PAR2 WHEN 0 THEN 'Default' ELSE 'Other' END AS Par2
END
GO

실행:

EXEC aaa_test 1
EXEC aaa_test 1,5

물체를 떨어뜨리면 안 됩니다.개체를 삭제하면 다음과 같은 두 가지 문제가 발생합니다.

CREATE에 실패하면 더 이상 개체가 없습니다. (많은 상용어구 코드를 사용하여 트랜잭션을 방지할 수 있습니다.)

개체를 명시적으로 다시 만들지 않으면 개체에 대한 사용 권한이 손실됩니다.


저는 "존재하지 않는 경우" 조건 내에서 빈 개체를 만든 다음 ALTER를 사용하고, 그 목적을 위해 서면 도우미 절차를 갖는 것을 선호합니다.

제가 이전에 답변한 내용에 대해서만 말씀드리겠습니다.

제가 선호하는 또 다른 이유는CREATE-ALTER위에DROP-CREATE접근.개체에 대한 특정 속성이 손실될 수 있습니다.예를들면ExecIsStartup:

USE master
GO

CREATE TABLE dbo.silly_logging(id INT IDENTITY(1,1) PRIMARY KEY
                               ,created_date DATETIME DEFAULT GETDATE()
                               ,comment VARCHAR(100));
GO

CREATE PROCEDURE dbo.my_procedure 
AS
INSERT INTO dbo.silly_logging(comment)
VALUES ('SQL Server Startup');
GO

-- mark procedure to start at SQL Server instance startup
EXEC sp_procoption @ProcName = 'dbo.my_procedure'
    , @OptionName = 'startup'   
    , @OptionValue = 'on';


SELECT name, create_date, modify_date, is_auto_executed
FROM master.sys.procedures
WHERE is_auto_executed = 1;
--name  create_date modify_date is_auto_executed
--my_procedure  2017-07-28 06:36:21.743 2017-07-28 06:36:24.513 1

이제 누군가가 다음을 사용하여 이 절차를 업데이트하려고 한다고 가정해 보겠습니다.DROP-CREATE:

DROP PROCEDURE dbo.my_procedure;
GO

CREATE PROCEDURE dbo.my_procedure 
AS
-- adding meaningless comment
INSERT INTO dbo.silly_logging(comment)
VALUES ('SQL Server Startup');
GO

SELECT name, create_date, modify_date, is_auto_executed
FROM master.sys.procedures
WHERE is_auto_executed = 1;
-- empty

그리고 만약 당신이 그것을 알지 못하거나 확인하지 않는다면 당신은 시작하지 않는 절차로 끝날 것입니다.

언급URL : https://stackoverflow.com/questions/1434160/what-do-you-do-in-sql-server-to-create-or-alter

반응형