为啥 s-s-rS 在已经定义时要求定义查询参数?

Posted

技术标签:

【中文标题】为啥 s-s-rS 在已经定义时要求定义查询参数?【英文标题】:why s-s-rS asking to Define query parameters when already defined?为什么 s-s-rS 在已经定义时要求定义查询参数? 【发布时间】:2019-02-25 13:43:01 【问题描述】:

我有以下在 SQL 中运行良好的查询。但是当我在 s-s-rs(Visual Studio 2015) 中使用这个查询时,它给了我一个错误,说定义查询参数。我已经为参数定义了值,但仍然出现错误。我从 s-s-rS 中不支持的 SQL 查询中感受到了一些东西。有人可以帮忙吗?

[![SET FMTONLY OFF

USE GODSDB

declare
@start date = getdate() - 100
,   @end date = getdate()
drop table #CallLog
declare @code varchar(max), @TableName varchar(max), @SeverName varchar(max)
--IF object_id('tempdb..#CallLog') IS NOT NULL DROP TABLE #CallLog
CREATE TABLE #CallLog (
\[JurisdictionShortIdentifier\] VARCHAR(100),
    \[ContractCallLogOID\] INT,
    \[ContractCallLogProcessQueueOID\] INT,
    \[ContractOID\] INT,
    \[CallDate\] DATETIME,
    \[CallHandledBy\] VARCHAR(60),
    \[CallLogOldGreenUnit\] INT,
    \[CallLogNewGreenUnit\] INT,
    \[Comment\] VARCHAR(7500)
)

set @TableName = '#CallLog'
set @SeverName = 'BA_GBASSTOCSISDB' -- sp_linkedservers
set @code = '
;with XMLNAMESPACES(DEFAULT ''http://tempuri.org/GEOUnit.xsd'')
select

    ccl.JurisdictionShortIdentifier,
    ccl.ContractCallLogOID,
    que.ContractCallLogProcessQueueOID,
    ccl.ContractOID,
    ccl.db_insertDate as CallDate,
    ccl.db_insertBy as CallHandledBy,
    convert(xml, que.XMLString).value(''(/GEOUnit/GreenPowerUnits/GreenPowerUnitsOld)\[1\]'',''int'') as CallLogOldGreenUnit,
    convert(xml, que.XMLString).value(''(/GEOUnit/GreenPowerUnits/GreenPowerUnitsNew)\[1\]'',''int'') as CallLogNewGreenUnit,
    cmt.Comment
from CSISDB.dbo.ContractCallLog as ccl (nolock)
left join CSISDB.dbo.ContractCallLogProcessQueue as que (nolock) on ccl.ContractCallLogOID = que.ContractCallLogOID
left join CSISDB.dbo.Comment as cmt (nolock) on ccl.ContractCallLogOID = cmt.FKObjectOID and cmt.FKTableObjectOID = 1008
where 1 = 1
and ccl.ContractCallLogStatusIdentifier in (''GMOD'', ''GUS'', ''GI'')
and ccl.ContractCallLogReasonIdentifier in (''Changed'', ''GEOR'', ''NULL'', ''GEO'', ''GEO0'', ''GEO1'', ''GEO3'', ''GEO2'', ''CDR'', ''GEO4'', ''GEO5'', ''JUST GREEN adder'', ''JustGreen'')
--and ccl.JurisdictionShortIdentifier = ''AG''
and ccl.SourceSystemIdentifier = ''GBASS''
and ccl.db_insertDate between @start and @end
--and ccl.ContractCallLogOID = 57131879 --> TEST CASE
'
set @code = replace(@code, '@start', '''' + convert(varchar, convert(date, @start, 101)) + '''')
set @code = replace(@code, '@end', '''' + convert(varchar, convert(date, dateadd(day, 1, @end), 101)) + '''')
set @code = concat('insert into ', @TableName, ' select * from openquery (', @SeverName, ', ''' , replace(@code, '''', '''''') , ''')')

print @code
exec(@code)

-- select * from #CallLog where ContractCallLogOID = 57707501

-- some call log have multiple process queues, delete the process queues that don't is not modifying the geo units
delete a
from #CallLog           as a
inner join #CallLog     as b    on a.ContractCallLogOID = b.ContractCallLogOID
                                and a.ContractCallLogProcessQueueOID != b.ContractCallLogProcessQueueOID
                                and a.CallLogNewGreenUnit is null
                                and b.CallLogNewGreenUnit is not null
--select * from #CallLog

select
    ccl.JurisdictionShortIdentifier,
    ccl.ContractCallLogOID,
    ccl.ContractCallLogProcessQueueOID,
    cnt.RtlrContractIdentifier,
    ccl.ContractOID,
    cst.ContractStatusIdentifier as ContractStatus,
    ccl.CallLogOldGreenUnit,
    ccl.CallLogNewGreenUnit,
    cur.GreenLevelIndicator as CurrentGreenUnit,
    cur.db_insertDate as GreenUnitLastUpdateDate,
    cur.db_insertBy as GreenUnitLastUpdateBy,
    ccl.CallDate,
    ccl.CallHandledBy,
    ccl.Comment
from #CallLog                       as ccl
inner join Contract                 as cnt (nolock) on ccl.ContractOID = cnt.ContractOID
                                                    and ccl.CallLogOldGreenUnit != ccl.CallLogNewGreenUnit
inner join ContractState            as cst (nolock) on cnt.ContractOID = cst.ContractOID
left join ContractGreenContent      as cur (nolock) on cnt.ContractOID = cur.ContractOID
                                                    and isnull(cur.EffectiveEndDate, dateadd(day, 1, getdate())) >= getdate()
left join ContractGreenContent      as his (nolock) on cnt.ContractOID = his.ContractOID
                                                    and ccl.CallLogNewGreenUnit = his.GreenLevelIndicator
                                                    and his.db_insertDate between dateadd(day, -1, ccl.CallDate) and dateadd(day, 1, ccl.CallDate)
where his.ContractGreenContentOID is null
--select * from #CallLog
union all

select
ccl.JurisdictionShortIdentifier,
    ccl.ContractCallLogOID,
    ccl.ContractCallLogProcessQueueOID,
    cnt.RtlrContractIdentifier,
    ccl.ContractOID,
    cst.ContractStatusIdentifier as ContractStatus,
    ccl.CallLogOldGreenUnit,
    ccl.CallLogNewGreenUnit,
    cur.GreenLevelIndicator as CurrentGreenUnit,
    cur.db_insertDate as GreenUnitLastUpdateDate,
    cur.db_insertBy as GreenUnitLastUpdateBy,
    ccl.CallDate,
    ccl.CallHandledBy,
    ccl.Comment
from #CallLog                       as ccl
inner join Contract                 as cnt (nolock) on ccl.ContractOID = cnt.ContractOID
                                                    and isnull(ccl.CallLogOldGreenUnit, 0) = isnull(ccl.CallLogNewGreenUnit, 0)
inner join ContractState            as cst (nolock) on cnt.ContractOID = cst.ContractOID
left join ContractGreenContent      as cur (nolock) on cnt.ContractOID = cur.ContractOID
                                                    and isnull(cur.EffectiveEndDate, dateadd(day, 1, getdate())) >= getdate()

SET FMTONLY ON][1]][1]

【问题讨论】:

【参考方案1】:

确保您的参数名称和 SQL 变量的拼写完全相同,它们区分大小写。

还可以尝试使用自己的 DECLARE 语句在自己的行上声明每个变量。我已经看到这个“有时”解决了这个问题

【讨论】:

【参考方案2】:

您的参数在您的@SQL 查询变量中。您运行 OPENQUERY 的服务器无法识别这些参数,因为它们是在另一台服务器上声明的。

将参数声明放入您的 SQL 变量中:

set @code = '
declare
@start date = getdate() - 100
,   @end date = getdate()
...

【讨论】:

以上是关于为啥 s-s-rS 在已经定义时要求定义查询参数?的主要内容,如果未能解决你的问题,请参考以下文章

在 XML 查询中显式定义数据类型,以便 s-s-rS 从 WCF 服务中识别

使用自定义代码 s-s-rS 从特定行获取值

s-s-rS 中的自定义 tablix 过滤器

s-s-rS 2008 R2 参数来自多选查询

带有 ODBC 连接的 s-s-rS 参数基础知识

来自视图的 s-s-rS 报告