2014-02-25 5 views
0

다음 TSQL 코드에서 처음 몇 줄에서 로컬 변수를 사용할 수 있으며 다시 사용할 수 없습니다. 코드의 마지막 줄에서 사용할 수없는 이유는 무엇입니까?TSQL에서 @@ 변수의 범위

범위는 어디에서 끝나나요? 여기

DECLARE @@CurrentDB varchar(50); 
SET @@CurrentDB = 'MyDBNAME'; 



-- Find Data & Log Fiel locations 
SELECT DB_NAME(database_id) AS DatabaseName, name AS LogicalFileName, physical_name AS PhysicalFileName, size/(128*1024) [GB] 
FROM sys.master_files AS mf 
WHERE DB_NAME(database_id) = @@CurrentDB 

-- Detach DB 
USE 
GO 
ALTER DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
GO 
USE [master] 
GO 
EXEC master.dbo.sp_detach_db @dbname = @@Cur 
GO 

오류입니다 : enter image description here

+0

난 당신이 [SQLCMD 모드 - 여기 예]를 사용하여 할 말은 생각 (http://dba.stackexchange.com/questions/46244/setting-variables-in-sqlcmd-mode).적어도 변수가 아니라면 Management Studio에서 일반 T-SQL을 사용하여이 작업을 수행 할 수 없습니다. –

+0

변수를 SSIS 패키지에 저장하고 원하는만큼 많은 SQL 실행 작업을 전달할 수 있습니다. 그 종류의 일이 너의 골목에 있다면. – Zane

답변

3

하여 SQL 서버 A GO 명령을 통과 할 때마다, 그 변수가 존재하는 상황을 종료하지 않으며 그것은에서 그 시점 이후에 아무것도에 의해 더 이상 액세스 할 수 T-SQL 코드. "글로벌"변수는 SQL Server에는 존재하지 않지만 일반적으로 전역 변수 테이블 (임시 또는 영구)을 구현함으로써 그 주위에 여러 가지 방법이 있습니다.

글로벌 변수를 추적하기위한 영구 테이블을 설정하는이 blog 게시물에서 일반적인 아이디어를 얻을 수 있습니다.

+3

나는 전역 변수 테이블이 아니라 전역 변수 테이블을 의미한다고 생각한다. (어떤 의미인지는 모르겠다.) –

+0

동의합니다. 나는 전역 변수 테이블을 알지 못하며 대개'## TempTables'에서 멀리 떨어져 있습니다. – Zane

+0

그럼 고맙습니다. 그래서 그것을 Table 변수에 넣고 거기에서 호출하십시오. 괜찮아. 감사. – ZeExplorer

0

는 해결 방법으로 사용할 수있는 Global Temp Table :

Declare @CurrentDB varchar(50) 
SET @CurrentDB = 'MyDBNAME' 
Create Table ##CurrentDB (Name varchar(50)) 
Insert Into ##CurrentDB Values (@CurrentDB) 
GO 
-- ... 
GO 
Declare @CurrentDB varchar(50) 
Select Top 1 @CurrentDB = Name From ##CurrentDB 
Select @CurrentDB 

당신이 당신의 스크립트의 각 부분에 서로 다른 데이터베이스를 사용하는 경우에도이 작동합니다.

+0

주의 할 점은 동시성이 정확히 1로 제한된다는 것입니다. 두 사용자가 해당 테이블을 만들려고 할 때 어떤 일이 발생하는지 추측하십시오. –

+0

또한 보통의'# temp' 테이블을 사용하여이 작업을 수행 할 수 있습니다. 전역 변수는 필요하지 않습니다. – JNK

+0

Aaron과 JNK는 절대적으로 적합합니다. – thepirat000

0

글로벌 변수 또는 임시 테이블을 사용하는 이유는 무엇입니까? 이것은 나에게 사용자 정의 스토어드 프로 시저가되도록 울부 짖는다.

다음은 비즈니스 규칙입니다.

1 - 기본적으로 분리하려는 데이터베이스의 위치와 크기를 가져오고 싶습니다.

2 - 단일 사용자 모드로 데이터베이스를 설정하고 싶습니다.

3 - 데이터베이스를 분리하려고합니다. 나중에 파일이 주위에 걸려있을 것입니다.

MSDB 데이터베이스에서 만들었지 만 도구 상자 데이터베이스에 저장할 수 있습니다.

데이터베이스가 실제로 사용 전용 모드인지 확인하지 않았습니다. - TODO 목록

sys.databases 테이블에서 모드를 확인하십시오. ALTER가 실패하면 분리를 시도하지 마십시오. 사용자에게 spids를 찾아서 죽일 것을 알리십시오.

http://technet.microsoft.com/en-us/library/ms178534.aspx

4 - 난에 처리 오류를 두지 않았다 -. TODO 목록

을하지 적어도 마지막으로,이 솔루션은 SQL 주입하는 경향이있을 수, 세계 액세스 권한을 부여하지 않습니다.

간단히 말해, 아래의 저장 프로 시저는 원하는대로 처리합니다.

-- 
-- Create a user stored procedure 
-- 

-- Start in msdb 
use msdb 
go 

-- drop existing 
if object_id('my_detach_process') > 0 
drop procedure my_detach_process 
go 

-- create new 
create procedure my_detach_process(@dbname sysname) 
as 

    -- Show the data 
    SELECT 
    DB_NAME(mf.database_id) AS DatabaseName, 
    mf.name AS LogicalName, 
    mf.physical_name AS PhysicalName, mf.size as SizeMb 
    FROM sys.master_files AS mf 
    WHERE DB_NAME(database_id) = @dbname; 

    -- Set to single user 
    DECLARE @sqlstmt1 nvarchar(512) = ''; 
    SET @sqlstmt1 = 'ALTER DATABASE [' + @dbname + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE'; 
    EXEC sp_executesql @sqlstmt1; 

    -- Detach 
    DECLARE @sqlstmt2 nvarchar(512) = ''; 
    SET @sqlstmt2 = 'USE [master]; EXEC master.dbo.sp_detach_db @dbname = ' + @dbname; 
    EXEC sp_executesql @sqlstmt2; 

GO 


-- 
-- Sample call 
-- 

-- Choose master 
use master 
go 

-- Create toy db 
create database toy; 
go 

-- Call the sp 
exec msdb.dbo.my_detach_process @dbname = 'Toy' 

샘플 호출의 샘플 출력.

enter image description here

+0

감사합니다. 나는 동의한다. 방금 UD SP를 만들 겠다는 생각을 바꿨습니다. – ZeExplorer

+0

하지만 동적 SQL을 사용하고 있습니다 ... 연결에서'QUOTENAME (@dbname)'을 사용해야합니다. – thepirat000

+0

@ thepirat000 정말 코드를 봐야합니다. 성명 하나는 이미 이름 옆에 []를 놓고있다. 데이터베이스 이름에 []을 (를) 입력하면 명령문 2가 실패합니다. 이것은 나쁜 제안입니다! –