我编写了一些动态SQL,执行后,它无法按预期运行。我在这里所做的是在动态SQL内声明了一些变量,并为该变量分配了一些值,然后使用EXEC命令在动态SQL内调用了另一个SP。
这是我编写的示例代码
declare
@TableName VARCHAR(250)='[PATS].Z_MTOReferenceDocument_307CAB4B_CC52_4BBA_8C3E_1481E1447028',
@LoginName VARCHAR(250)='dHANIL',
@Date DATETIME='8-May-2020',
@ProjectID UNIQUEIDENTIFIER='e50e25a7-3d8e-4d1d-b401-942e51ab5f7f',
@DocumentOwnerID UNIQUEIDENTIFIER='fc938df0-8a4e-4c85-b93c-be51373c559f'
declare @sampleSQL nvarchar(max)=''
set @sampleSQL=(' DECLARE @ApprovalStatus INT=NULL,'
+' @DocumentHeaderID UNIQUEIDENTIFIER,'
+' @Status INT'
+' SELECT @ApprovalStatus=ApprovalStatusCode,@DocumentHeaderID=DH.ID FROM '+@TableName+' TT'
+' LEFT JOIN [PI].[DocumentHeader] DH ON DH.[DocumentNo]=TT.[Document No] WHERE LatestRevYN=''1'''
+' IF(@ApprovalStatus=''4'')'
+' BEGIN'
+' EXEC [PI].[ReviseDocument] @DocumentHeaderID,'''+@LoginName+''','''+CAST(@Date AS NVARCHAR(100))+''',''Document revised through Import'',@Status OUTPUT,@ID OUTPUT,@DocumentID OUTPUT'
+' END')
而且有趣的是,当它不是动态查询时,它就可以工作。在动态查询中使用EXEC命令是否存在任何问题。
因此,这不能解决为什么您的动态SQL无法正常工作的问题。我的猜测是一个范围界定问题,但是您随后执行存储过程的动态SQL使我想起了电影《盗梦空间》-梦中的梦。
根据我看到的代码,我的建议只是使必要的部分动态化,即表名。其余的可以是静态的,例如
DECLARE @TableName VARCHAR(250) = '[PATS].Z_MTOReferenceDocument_307CAB4B_CC52_4BBA_8C3E_1481E1447028'
, @LoginName VARCHAR(250) = 'dHANIL'
, @Date DATETIME = '8-May-2020'
, @ProjectID UNIQUEIDENTIFIER = 'e50e25a7-3d8e-4d1d-b401-942e51ab5f7f'
, @DocumentOwnerID UNIQUEIDENTIFIER = 'fc938df0-8a4e-4c85-b93c-be51373c559f';
DECLARE @SampleSQL NVARCHAR(MAX) = '';
DECLARE @ApprovalStatus INT = NULL, @DocumentHeaderID UNIQUEIDENTIFIER, @Status INT;
SET @SampleSQL = ' SELECT @ApprovalStatus = ApprovalStatusCode, @DocumentHeaderID = DH.ID FROM ' + @TableName + ' TT'
+ ' LEFT JOIN [PI].[DocumentHeader] DH ON DH.[DocumentNo] = TT.[Document No] WHERE LatestRevYN = ''1''';
EXEC SP_EXECUTESQL @SampleSQL, N'@ApprovalStatus INT OUTPUT, @DocumentHeaderID UNIQUEIDENTIFIER OUTPUT', @ApprovalStatus = @ApprovalStatus OUTPUT, @DocumentHeaderID = @DocumentHeaderID OUTPUT;
IF @ApprovalStatus = 4
BEGIN
EXEC [PI].[ReviseDocument] @DocumentHeaderID, @LoginName, @Date, 'Document revised through Import', @Status OUTPUT, @ID OUTPUT, @DocumentID OUTPUT;
END;
希望该概念可以延续到您的实际SQL中。