动态sql server查询中的参数

时间:2015-01-26 09:04:56

标签: sql-server

我在动态查询中传递参数有问题。这是错误消息

  

消息50000,级别11,状态1,过程WriteJobLog,第101行错误   写作业日志:第90行:[ERR]#7:必须声明标量变量   “@LastId”。

我的sql代码是:

ALTER PROCEDURE [WarehouseMgmt].[SyncReportServerFormatEntries]
    @SyncJobId varchar(50),
    @SyncJobStep varchar(50)=NULL, -- Sproc name will be used as a job step if not specified
    @SyncExecId int=NULL, -- Will be obtained from @SyncJobStep step execution if not specified
    @LastId BIGINT=NULL, -- Last transaction id to snyc, will be obtained from WarehouseMgmt.SyncSQLData if not specified
    @SyncObjectName VARCHAR(50) = 'WarehouseMgmt.FactReportServerExecutionLog'
AS
..........
DECLARE @sql nvarchar(max);
        DECLARE @server nvarchar(255) = (SELECT [Value] FROM [WarehouseMgmt].[SyncConfig] WHERE [Key] = 'ReportServerLinkedServer')
        DECLARE @database nvarchar(255) = (SELECT [Value] FROM [WarehouseMgmt].[SyncConfig] WHERE [Key] = 'ReportServerDatabase')

        SET @sql='MERGE [WarehouseMgmt].[DimReportServerFormatEntries] AS Target
        USING( 
                  SELECT CASE [Format]
                  WHEN ''RPL'' THEN ''View''
                  ELSE ''Export'' 
                  END [Name],
                  [Format] [OriginalFormatName],
                  LogEntryId 
                  FROM OPENQUERY('+@server+',
                  ''SELECT CASE [Format]
                  WHEN ''''RPL'''' THEN ''''View''''
                  ELSE ''''Export'''' 
                  END [Name],
                  [Format] [OriginalFormatName],
                  LogEntryId  
                  FROM '+@database+'.dbo.[ExecutionLogStorage] WHERE LogEntryId > @LastId AND [Parameters] IS NOT NULL '' )               

              ) AS Source
        ON Source.LogEntryId=Target.SourceOrigId
        WHEN NOT MATCHED BY TARGET THEN
            INSERT 
            (
                [Name],
                [OriginalFormatName],
                [SourceOrigId],
                SyncExecId
            )
            VALUES 
            (
                ISNULL(Source.[Name],''<UNKNOWN>''),
                ISNULL(Source.[OriginalFormatName],''<UNKNOWN>''),
                Source.[LogEntryId],
                @SyncExecId
            )
            OUTPUT  
                ISNULL(Source.[Name],''<UNKNOWN>''),
                ISNULL(Source.[OriginalFormatName],''<UNKNOWN>''),
                Source.[LogEntryId]
            INTO #NewReportServerFormatEntries;' 

        EXEC sp_executesql @sql,N'@LastId bigint,@SyncExecId int',@LastId,@SyncExecId;

2 个答案:

答案 0 :(得分:1)

不确定您是否可以从将参数传递到动态SQL中获益良多。也许试试没有参数?

ALTER PROCEDURE [WarehouseMgmt].[SyncReportServerFormatEntries]
    @SyncJobId varchar(50),
    @SyncJobStep varchar(50)=NULL, -- Sproc name will be used as a job step if not specified
    @SyncExecId int=NULL, -- Will be obtained from @SyncJobStep step execution if not specified
    @LastId BIGINT=NULL, -- Last transaction id to snyc, will be obtained from WarehouseMgmt.SyncSQLData if not specified
    @SyncObjectName VARCHAR(50) = 'WarehouseMgmt.FactReportServerExecutionLog'
AS
..........
DECLARE @sql nvarchar(max);
        DECLARE @server nvarchar(255) = (SELECT [Value] FROM [WarehouseMgmt].[SyncConfig] WHERE [Key] = 'ReportServerLinkedServer')
        DECLARE @database nvarchar(255) = (SELECT [Value] FROM [WarehouseMgmt].[SyncConfig] WHERE [Key] = 'ReportServerDatabase')

        SET @sql='MERGE [WarehouseMgmt].[DimReportServerFormatEntries] AS Target
        USING( 
                  SELECT CASE [Format]
                  WHEN ''RPL'' THEN ''View''
                  ELSE ''Export'' 
                  END [Name],
                  [Format] AS [OriginalFormatName],
                  LogEntryId 
                  FROM OPENQUERY('+@server+',
                  ''SELECT CASE [Format]
                  WHEN ''''RPL'''' THEN ''''View''''
                  ELSE ''''Export'''' 
                  END [Name],
                  [Format],
                  LogEntryId  
                  FROM '+@database+'.dbo.[ExecutionLogStorage] WHERE LogEntryId > ' + ISNULL(CAST(@LastId AS NVARCHAR(MAX)), 'NULL') + ' AND [Parameters] IS NOT NULL '' )               

              ) AS Source
        ON Source.LogEntryId=Target.SourceOrigId
        WHEN NOT MATCHED BY TARGET THEN
            INSERT 
            (
                [Name],
                [OriginalFormatName],
                [SourceOrigId],
                SyncExecId
            )
            VALUES 
            (
                ISNULL(Source.[Name],''<UNKNOWN>''),
                ISNULL(Source.[OriginalFormatName],''<UNKNOWN>''),
                Source.[LogEntryId],
                ' + ISNULL(CAST(@SyncExecId AS NVARCHAR(MAX)), 'NULL') + '
            )
            OUTPUT  
                ISNULL(Source.[Name],''<UNKNOWN>''),
                ISNULL(Source.[OriginalFormatName],''<UNKNOWN>''),
                Source.[LogEntryId]
            INTO #NewReportServerFormatEntries;' 

        EXEC sp_executesql @sql;

答案 1 :(得分:-2)

由于@LastId和@SyncExecId已作为参数存入此存储过程,为什么不构建连接实际值的SQL语句?试试这个。请注意转换(varchar(250)短语中这些参数的直接串联,其中参数的引用先前存在于您的代码中。

SET @sql='MERGE [WarehouseMgmt].[DimReportServerFormatEntries] AS Target
        USING( 
                  SELECT CASE [Format]
                  WHEN ''RPL'' THEN ''View''
                  ELSE ''Export'' 
                  END [Name],
                  [Format] [OriginalFormatName],
                  LogEntryId 
                  FROM OPENQUERY('+@server+',
                  ''SELECT CASE [Format]
                  WHEN ''''RPL'''' THEN ''''View''''
                  ELSE ''''Export'''' 
                  END [Name],
                  [Format] [OriginalFormatName],
                  LogEntryId  
                  FROM '+@database+'.dbo.[ExecutionLogStorage] WHERE LogEntryId > ' + convert(varchar(250), @LastId) + ' AND [Parameters] IS NOT NULL '' )               

              ) AS Source
        ON Source.LogEntryId=Target.SourceOrigId
        WHEN NOT MATCHED BY TARGET THEN
            INSERT 
            (
                [Name],
                [OriginalFormatName],
                [SourceOrigId], ' + convert(varchar(250), @SyncExecId) + '
            )
            VALUES 
            (
                ISNULL(Source.[Name],''<UNKNOWN>''),
                ISNULL(Source.[OriginalFormatName],''<UNKNOWN>''),
                Source.[LogEntryId], ' + convert(varchar(250), @SyncExecId) + '
            )
            OUTPUT  
                ISNULL(Source.[Name],''<UNKNOWN>''),
                ISNULL(Source.[OriginalFormatName],''<UNKNOWN>''),
                Source.[LogEntryId]
            INTO #NewReportServerFormatEntries;'