>  기사  >  데이터 베이스  >  SQL Server가 관련 동적 SQL을 실행하는 올바른 방법을 설명합니다.

SQL Server가 관련 동적 SQL을 실행하는 올바른 방법을 설명합니다.

巴扎黑
巴扎黑원래의
2017-08-11 15:25:331048검색

이 글에서는 주로 SQL Server가 동적 SQL을 실행하는 올바른 방법을 소개합니다. 필요한 친구들은 참고하면 됩니다.

SQL Server가 동적 SQL을 실행한다면, 다음은 어떻게 구현해야 할까요? SQL Server에서 동적 SQL을 실행하는 방법을 통해 SQL Server에서 실행되는 동적 SQL에 대해 더 깊이 이해할 수 있기를 바랍니다. 동적 SQL: 일반적으로 사용자 입력을 기반으로 동적으로 결합되는 SQL 문 블록입니다. 동적 SQL은 SQL의 힘을 유연하게 발휘할 수 있습니다. 다른 방법으로는 해결하기 어려운 일부 문제를 기능적이고 편리하게 해결할 수 있습니다. 하지만 동적 SQL을 사용해 본 사람이라면 누구나 그 편리함을 이해할 수 있을 것입니다.

동적 SQL은 실행 성능(효율성) 측면에서 정적 SQL만큼 좋지 않고 부적절하게 사용되는 경우가 많습니다.

동적 SQL은 EXECUTE 또는 두 가지 방법으로 실행될 수 있습니다. SP_EXECUTESQL.

EXECUTE

  执行 Transact-SQL 批中的命令字符串、字符串或执行下列模块之一:系统存储过程、用户定义存储过程、标量值用户定义函数或扩展存储过程.SQL Server 2005 扩展了 EXECUTE 语句,以使其可用于向链接服务器发送传递命令.此外,还可以显式设置执行字符串或命令的上下文

  SP_EXECUTESQL EXECUTE

Transact-SQL 일괄 실행 문자열의 명령 문자열 또는 다음 모듈 중 하나를 실행합니다. 시스템 저장 프로시저, 사용자 정의 저장 프로시저, 스칼라 값이 있는 사용자 정의 함수 또는 확장 저장 프로시저는 연결에 사용할 수 있도록 EXECUTE 문을 확장합니다. 또한 서버는 문자열이나 명령을 실행하기 위한 컨텍스트를 명시적으로 설정할 수 있습니다.

  SP_EXECUTESQL

 Transact-SQL 문 또는 일괄 처리는 여러 번 재사용되거나 동적으로 생성될 수 있습니다. SP_EXECUTESQL은 일괄 처리와 관련하여 EXECUTE와 동일하게 동작합니다. 이름 범위 및 데이터베이스 컨텍스트 SP_EXECUTESQL stmt 매개 변수의 일괄 처리는 SP_EXECUTESQL 문이 실행될 때까지 컴파일되지 않고 실행 계획으로 실행됩니다. SP_EXECUTESQL이라는 일괄 처리 계획은 SP_EXECUTESQL 일괄 처리에 선언된 변수를 참조할 수 없습니다. SP_EXECUTESQL 일괄 처리의 로컬 커서나 변수는 SP_EXECUTESQL을 호출하는 일괄 처리에 표시되지 않습니다. SP_EXECUTESQL 문에서 매개변수 값만 변경되면 저장 프로시저 대신 sp_executesql을 사용할 수 있습니다. Transact-SQL 문 자체는 변경되지 않고 매개변수 값만 유지되므로 Transact-SQL 문을 여러 번 실행합니다. 변경하면 SQL Server 쿼리 최적화 프로그램은 첫 번째 실행 중에 생성된 실행 계획을 재사용할 수 있습니다.

일반적으로 SP_EXECUTESQL을 사용하여 동적 SQL을 실행하는 것이 더 유연하고 입력 및 실행이 가능합니다. 반면에 쿼리 최적화 프로그램은 실행 계획을 재사용하고 실행 효율성을 향상시킬 가능성이 높습니다. 또한 SP_EXECUTESQL을 사용하면 보안이 향상될 수 있습니다. 물론 이는 특정 상황에서 EXECUTE를 완전히 포기해야 한다는 의미는 아닙니다. EXECUTE는 SP_EXECUTESQL보다 더 편리합니다. 예를 들어 동적 SQL 문자열은 NVARCHAR 유형이 아닌 VARCHAR 유형입니다. SP_EXECUTESQL은 유니코드 문자열만 실행할 수 있거나 암시적으로 ntext 상수 또는 변수로 변환될 수 있으며 EXECUTE는 두 가지 유형의 문자열을 모두 실행할 수 있습니다.

EXECUTE와 SP_EXECUTESQL의 세부 사항을 비교해 보겠습니다.

EXECUTE(N'SELECT * FROM Groups') - -실행 성공

  EXECUTE('SELECT * FROM Groups') --실행 성공

 SP_EXECUTESQL N'SELECT * FROM Groups'; --실행 성공

 SP_EXECUTESQL 'SELECT * FROM Groups' --실행 오류

 요약: EXECUTE는 유니코드가 아닌 또는 유니코드 유형의 문자열 상수와 변수만 실행할 수 있습니다. 암시적으로 ntext로 변환됩니다.

  DECLARE @GroupName VARCHAR(50);SET@GroupName =' SuperAdmin';

 EXECUTE('SELECT * FROM Groups WHERE GroupName=''' + SUBSTRING(@GroupName, 1,5) + ''''); --'SUBSTRING' 근처에 구문 오류가 있습니다.

 DECLARE @Sql VARCHAR(200);

  DECLARE @GroupName VARCHAR(50);

  SET@ Sql='SELECT * FROM 그룹 WHERE GroupName=''' + SUBSTRING(@GroupName, 1,5) + ''''

 --PRINT @Sql;EXECUTE(@Sql);

 요약: EXECUTE 대괄호는 다음을 수행할 수 있습니다. 문자열 변수, 문자열 상수 또는 이들의 조합만 포함합니다. 다른 함수 및 저장소 등을 호출할 수 없습니다. 사용하려면 위와 같이 변수 조합을 사용하세요.

  DECLARE @Sql VARCHAR(200);

DECLARE @GroupName VARCHAR(50); SET@GroupName ='SuperAdmin';

 SET@Sql= 'SELECT * FROM Groups WHEREGroupName=@GroupName'

  --PRINT @Sql;EXECUTE(@Sql); 스칼라 변수 "@GroupName"을 선언해야 합니다.SET@Sql='SELECT * FROM Groups WHERE GroupName=' + QUOTENAME(@GroupName, '''')

  EXECUTE(@Sql); --올바른:

  DECLARE @Sql NVARCHAR(200);

  DECLARE @GroupName NVARCHAR(50);SET@GroupName ='SuperAdmin' ;

  SET@Sql='SELECT * FROM Groups WHEREGroupName=@GroupName'

  PRINT @Sql;

  EXEC SP_EXECUTESQL @ SQL,N'@GroupNameNVARCHAR',@GroupName

 쿼리 결과가 없고 매개변수 길이가 선언되지 않았습니다.

 DECLARE @Sql NVARCHAR(200);

 DECLARE @GroupName NVARCHAR(50);SET@GroupName ='SuperAdmin';

 SET@Sql ='SELECT * FROM Groups WHERE GroupName=@GroupName'

 PRINT @Sql;

  EXEC SP_EXECUTESQL @Sql, N'@GroupName NVARCHAR(50)',@GroupName

  요약: 동적 일괄 처리에서는 다음에 정의된 로컬 변수에 액세스할 수 없습니다. SP_EXECUTESQL EXECUTE보다 유연한 입력 및 출력 매개변수를 가질 수 있습니다. EXECUTE 및 SP_EXECUTESQL의 실행 효율성을 살펴보겠습니다. 먼저 캐시 실행 계획을 지운 다음 @GroupName 값을 변경하여 SuperAdmin을 실행합니다. , CommonUser 및 CommonAdmin을 각각 세 번 살펴보세요. --'CommonUser', 'CommonAdmin'

 SET@ Sql ='SELECT * FROM 그룹 WHERE GroupName=' + QUOTENAME(@GroupName, '''')

  EXECUTE(@Sql); 캐시%'

 ANDsql NOTLIKE '%sys.%';

 예제를 따르기 위해 SP_EXECUTESQL

 DBCC FREEPROCCACHE;

 DECLARE @Sql NVARCHAR(200);

 DECLARE @GroupName NVARCHAR (50);SET@GroupName의 실행 효율성을 살펴보겠습니다. ='SuperAdmin'; --'CommonUser', 'CommonAdmin'

 SET@Sql ='SELECT * FROM 그룹 WHERE GroupName=@GroupName'

 EXECUTESP_EXECUTESQL @Sql, N'@GroupName NVARCHAR( 50) ', @GroupName; 요약: EXEC 생성 세 개의 독립적인 임시 실행 계획이 있지만 SP_EXECUTESQL을 사용하면 하나의 실행 계획만 생성되고 세 번 재사용됩니다. 라이브러리에 이와 같은 유사한 동적 SQL이 많고 SP_EXECUTESQL이 자주 실행된다고 상상해 보십시오.

다음은 다른 네티즌들이 추가한 내용입니다

몇 가지 특별한 이유로 인해 SQL 문이나 저장 프로시저에서 SQL 문을 동적으로 생성한 다음 이를 SQL 문이나 저장 프로시저에서 동적으로 실행해야 합니다. 절차.

여기서 Microsoft는 두 가지 방법을 제공합니다. 하나는

Execute 함수를 사용하는 것입니다.

실행 방법은

Execute(@sql)로 SQL 문을 동적으로 실행하지만 여기의 SQL 문은 반환 결과를 얻을 수 없습니다. 또 다른 방법을 소개하겠습니다

저장 프로시저를 사용하여

sp_ExecuteSql

이 저장 프로시저를 사용하면 동적 문에서 매개 변수를 반환할 수 있습니다.

예를 들어

declare @sql nvarchar(800),@dd varchar(20)
set @sql='set @mm=''测试字符串'''
exec sp_executesql @sql,N'@mm varchar(20) output',@dd output
select @dd

이 실행되면 내부에서 생성된 SQL 문의 변수 값이 외부 호출자에게 반환됩니다.

주로 직장에서 우연한 필요로 인해 발생합니다.

create proc proc_InToServer @收费站点编号 varchar(4),@车道号 tinyint,@进入时间 varchar(23),@UID char(16),
@车牌 varchar(12),@车型 char(1),@识别车牌号 varchar(12),@识别车型 char(1),@收费金额 money,@交易状态 char(1),
@有图像 bit,@离开时间 varchar(23),@速度 float,@HasInsert int output
as
begin
  declare @inTime datetime,@TableName varchar(255),@leaveTime datetime,@HasTable bit,@Sql nvarchar(4000)
 select @intime=Convert(datetime,@进入时间),@leaveTime=Convert(datetime,@离开时间)
 set @TableName='ETC03_01_OBE原始过车记录表_'+dbo.formatDatetime(@intime,'YYYYMMDD')

 select @HasTable=(Case when Count(*)>0 then 1 else 0 end) from sysobjects where id=Object_id(@TableName) and ObjectProperty(id,'IsUserTable')=1
 if @HasTable=0
 begin
  set @Sql='CREATE TABLE [dbo].['+@TableName+'] (
 [收费站点编号] [char] (4) COLLATE Chinese_PRC_CI_AS NOT NULL,
 [车道号] [tinyint] NOT NULL,
 [进入时间] [datetime] NOT NULL,
 [UID] [char] (16) COLLATE Chinese_PRC_CI_AS NOT NULL,
 [车牌] [varchar] (12) COLLATE Chinese_PRC_CI_AS NULL ,
 [车型] [char] (1) COLLATE Chinese_PRC_CI_AS NULL ,
 [识别车牌号] [varchar] (12) COLLATE Chinese_PRC_CI_AS NULL ,
 [识别车型] [char] (1) COLLATE Chinese_PRC_CI_AS NULL ,
 [收费金额] [money] NULL ,
 [交易状态] [char] (1) COLLATE Chinese_PRC_CI_AS NULL ,
 [有图像] [bit] NOT NULL ,
 [离开时间] [datetime] NULL ,
 [速度] [float] NULL,
    Constraint'+' PK_'+@TableName+' primary key(收费站点编号,车道号,进入时间,UID)
    ) ON [PRIMARY]'
   Execute(@Sql)
  end 
  set @sql = 'select @Cnt=count(*) from '+@TableName+ ' where 收费站点编号='''+@收费站点编号+''' and 车道号='+cast(@车道号 as varchar(4))+' and 进入时间='''+@进入时间+''' and UID='''+@UID+''''
  set @sql = @sql + ' if @Cnt=0 '
  
  set @sql=@sql+'insert '+@TableName+' values('''+@收费站点编号+''','+cast(@车道号 as varchar(4))+','''+@进入时间+''','''+@Uid+''','''+@车牌+  
  ''','''+@车型+''','''+  @识别车牌号+''','''+@识别车型+''','+Cast(@收费金额 as varchar(8))+','''+@交易状态+''','+cast(@有图像 as varchar(1))+
  ','''+@离开时间+''','+Cast(@速度 as varchar(8))+')'
  --Execute(@sql) 
  exec sp_executesql @sql,N'@Cnt int output',@HasInsert output
end

보충 정보 2.


SQL Server는 동적 SQL 문을 실행하기 위해 루프를 실행합니다.

Navicate 도구를 사용하여 쿼리를 성공적으로 실행합니다.

rreee

위 내용은 SQL Server가 관련 동적 SQL을 실행하는 올바른 방법을 설명합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.