IT TIP

이동 중에 변수를 유지하는 방법이 있습니까?

itqueen 2020. 10. 23. 19:48
반응형

이동 중에 변수를 유지하는 방법이 있습니까?


이동 중에 변수를 유지하는 방법이 있습니까?

Declare @bob as varchar(50);
Set @bob = 'SweetDB'; 
GO
USE @bob  --- see note below
GO
INSERT INTO @bob.[dbo].[ProjectVersion] ([DB_Name], [Script]) VALUES (@bob,'1.2')

이 참조 SO의 '사용 @bob'라인에 대한 질문을.


go명령은 코드를 별도의 배치로 분할하는 데 사용됩니다. 그것이 정확히 당신이하고 싶은 일이라면 그것을 사용해야하지만 그것은 배치가 실제로 분리되어 있고 그들 사이에 변수를 공유 할 수 없다는 것을 의미합니다.

귀하의 경우 솔루션은 간단합니다. go명령문을 제거 할 수 있으며 해당 코드에서 필요하지 않습니다.

참고 : use에서 변수를 사용할 수 없으며 데이터베이스의 이름이어야합니다.


임시 테이블 사용 :

CREATE TABLE #variables
    (
    VarName VARCHAR(20) PRIMARY KEY,
    Value VARCHAR(255)
    )
GO

Insert into #variables Select 'Bob', 'SweetDB'
GO

Select Value From #variables Where VarName = 'Bob'
GO

DROP TABLE #variables
go

내가 선호하는 이 질문에서 답을 GO 글로벌 변수

원래하고 싶었던 일을 할 수 있다는 추가적인 이점이 있습니다.

주의 할 점은 SQLCMD 모드 (Query-> SQLCMD 아래)를 켜거나 모든 쿼리 창에 대해 기본적으로 켜야한다는 것입니다 (도구-> 옵션 다음 쿼리 결과-> 기본적으로 SQLCMD 모드에서 새 쿼리 열기).

그런 다음 다음 유형의 코드를 사용할 수 있습니다 ( Oscar E. Fraxedas Tormo의 동일한 답변에서 완전히 찢어짐 )

--Declare the variable
:setvar MYDATABASE master
--Use the variable
USE $(MYDATABASE);
SELECT * FROM [dbo].[refresh_indexes]
GO
--Use again after a GO
SELECT * from $(MYDATABASE).[dbo].[refresh_indexes];
GO

잘 모르겠습니다. 도움이된다면

declare @s varchar(50)
set @s='Northwind'

declare @t nvarchar(100)
set @t = 'select * from ' + @s + '.[dbo].[Customers]'

execute sp_executesql @t

SQL Server를 사용하는 경우 다음과 같은 전체 스크립트에 대한 전역 변수를 설정할 수 있습니다.

:setvar sourceDB "lalalallalal"

나중에 스크립트에서 다음과 같이 사용하십시오.

$(sourceDB)

Server Managment Studi에서 SQLCMD 모드가 켜져 있는지 확인하십시오. 상단 메뉴를 통해 수행 할 수 있습니다. 쿼리를 클릭하고 SQLCMD 모드를 켜십시오.

주제에 대한 자세한 내용은 여기에서 찾을 수 있습니다. MS 문서


임시 테이블은 GO 문을 통해 유지되므로 ...

SELECT 'value1' as variable1, 'mydatabasename' as DbName INTO #TMP

-- get a variable from the temp table
DECLARE @dbName VARCHAR(10) = (select top 1 #TMP.DbName from #TMP)
EXEC ('USE ' + @dbName)
GO

-- get another variable from the temp table
DECLARE @value1 VARCHAR(10) = (select top 1 #TMP.variable1 from #TMP)

DROP TABLE #TMP

예쁘지는 않지만 작동합니다.


임시 테이블에 저장 /로드하는 고유 한 저장 프로 시저를 만듭니다.

MyVariableSave   -- Saves variable to temporary table. 
MyVariableLoad   -- Loads variable from temporary table.

그런 다음 이것을 사용할 수 있습니다.

print('Test stored procedures for load/save of variables across GO statements:')

declare @MyVariable int = 42
exec dbo.MyVariableSave @Name = 'test', @Value=@MyVariable
print('  - Set @MyVariable = ' + CAST(@MyVariable AS VARCHAR(100)))

print('  - GO statement resets all variables')
GO -- This resets all variables including @MyVariable

declare @MyVariable int
exec dbo.MyVariableLoad 'test', @MyVariable output
print('  - Get @MyVariable = ' + CAST(@MyVariable AS VARCHAR(100)))

산출:

Test stored procedures for load/save of variables across GO statements:
  - Set @MyVariable = 42
  - GO statement resets all variables
  - Get @MyVariable = 42

다음을 사용할 수도 있습니다.

exec dbo.MyVariableList       -- Lists all variables in the temporary table.
exec dbo.MyVariableDeleteAll  -- Deletes all variables in the temporary table.

출력 exec dbo.MyVariableList:

Name    Value
test    42

테이블에있는 모든 변수를 나열 할 수있는 것은 실제로 매우 유용합니다. 따라서 나중에 변수를로드하지 않더라도 모든 것을 한곳에서 볼 수있는 디버깅 목적으로 좋습니다.

이것은 ##접두사 가있는 임시 테이블을 사용 하므로 GO 문에서 살아남기에 충분합니다. 단일 스크립트 내에서 사용하기위한 것입니다.

그리고 저장 프로 시저 :

-- Stored procedure to save a variable to a temp table.
CREATE OR ALTER PROCEDURE MyVariableSave 
    @Name varchar(255),
    @Value varchar(MAX)
WITH EXECUTE AS CALLER
AS  
BEGIN
    SET NOCOUNT ON
    IF NOT EXISTS (select TOP 1 * from tempdb.sys.objects where name = '##VariableLoadSave')
    BEGIN
        DROP TABLE IF EXISTS ##VariableLoadSave
        CREATE TABLE ##VariableLoadSave
        (
            Name varchar(255),
            Value varchar(MAX)
        )
    END
    UPDATE ##VariableLoadSave SET Value=@Value WHERE Name=@Name
    IF @@ROWCOUNT = 0
        INSERT INTO ##VariableLoadSave SELECT @Name, @Value
END
GO
-- Stored procedure to load a variable from a temp table.
CREATE OR ALTER PROCEDURE MyVariableLoad 
    @Name varchar(255),
    @Value varchar(MAX) OUT
WITH EXECUTE AS CALLER
AS  
BEGIN
    IF EXISTS (select TOP 1 * from tempdb.sys.objects where name = '##VariableLoadSave')
    BEGIN
        IF NOT EXISTS(SELECT TOP 1 * FROM ##VariableLoadSave WHERE Name=@Name)
        BEGIN
            declare @ErrorMessage1 as varchar(200) = 'Error: cannot find saved variable to load: ' + @Name
            raiserror(@ErrorMessage1, 20, -1) with log
        END

        SELECT @Value=CAST(Value AS varchar(MAX)) FROM ##VariableLoadSave
        WHERE Name=@Name
    END
    ELSE
    BEGIN
        declare @ErrorMessage2 as varchar(200) = 'Error: cannot find saved variable to load: ' + @Name
        raiserror(@ErrorMessage2, 20, -1) with log
    END
END
GO
-- Stored procedure to list all saved variables.
CREATE OR ALTER PROCEDURE MyVariableList
WITH EXECUTE AS CALLER
AS  
BEGIN
    IF EXISTS (select TOP 1 * from tempdb.sys.objects where name = '##VariableLoadSave')
    BEGIN
        SELECT * FROM ##VariableLoadSave
        ORDER BY Name
    END
END
GO
-- Stored procedure to delete all saved variables.
CREATE OR ALTER PROCEDURE MyVariableDeleteAll
WITH EXECUTE AS CALLER
AS  
BEGIN
    DROP TABLE IF EXISTS ##VariableLoadSave
    CREATE TABLE ##VariableLoadSave
    (
        Name varchar(255),
        Value varchar(MAX)
    )
END

바이너리 예 / 아니오 (예 : 열이있는 경우) 만 필요한 경우 SET NOEXEC ON문 실행을 비활성화 하는 데 사용할 수 있습니다 . SET NOEXEC ONGO (배치 전체)에서 작동합니다. 그러나 에 EXEC를 다시 설정하는 기억SET NOEXEC OFF스크립트의 끝에서.

IF COL_LENGTH('StuffTable', 'EnableGA') IS NOT NULL
    SET NOEXEC ON -- script will not do anything when column already exists

ALTER TABLE dbo.StuffTable ADD EnableGA BIT NOT NULL CONSTRAINT DF_StuffTable_EnableGA DEFAULT(0)
ALTER TABLE dbo.StuffTable SET (LOCK_ESCALATION = TABLE)
GO
UPDATE dbo.StuffTable SET EnableGA = 1 WHERE StuffUrl IS NOT NULL
GO
SET NOEXEC OFF

This compiles statements but does not execute them. So you'll still get "compile errors" if you reference schema that doesn't exist. So it works to "turn off" the script 2nd run (what I'm doing), but does not work to turn off parts of the script on 1st run, because you'll still get compile errors if referencing columns or tables that don't exist yet.


You can make use of NOEXEC follow he steps below:

Create table

#temp_procedure_version(procedure_version varchar(5),pointer varchar(20))

insert procedure versions and pointer to the version into a temp table #temp_procedure_version

--example procedure_version pointer

insert into temp_procedure_version values(1.0,'first version')

insert into temp_procedure_version values(2.0,'final version')

then retrieve the procedure version, you can use where condition as in the following statement

Select @ProcedureVersion=ProcedureVersion from #temp_procedure_version where pointer='first version'

IF (@ProcedureVersion='1.0')
    BEGIN
    SET NOEXEC OFF  --code execution on 
    END
ELSE
    BEGIN 
    SET NOEXEC ON  --code execution off
    END 

--insert procedure version 1.0 here

Create procedure version 1.0 as.....

SET NOEXEC OFF -- execution is ON

Select @ProcedureVersion=ProcedureVersion from #temp_procedure_version where pointer='final version'

IF (@ProcedureVersion='2.0')
    BEGIN
    SET NOEXEC OFF  --code execution on 
    END
ELSE
    BEGIN 
    SET NOEXEC ON  --code execution off
    END 

Create procedure version 2.0 as.....

SET NOEXEC OFF -- execution is ON

--drop the temp table

Drop table #temp_procedure_version

참고URL : https://stackoverflow.com/questions/937336/is-there-a-way-to-persist-a-variable-across-a-go

반응형