首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在OpenQuery中执行存储过程缺少什么?

在OpenQuery中执行存储过程缺少什么?
EN

Stack Overflow用户
提问于 2020-12-11 21:07:15
回答 1查看 230关注 0票数 0

我试图使用OpenQuery将数据插入到临时表中。OpenQuery假设执行一个输出数百行的存储过程。

为了不定义Create Table #temp1,我尝试执行OpenQuery并使用Select查询中的into语句将结果插入到#temp1表中。我想知道是什么原因导致它不执行?

  1. ,似乎它可能引用了没有正确放置的问题。我怎样才能得到与此相关的帮助?

  1. My包含多个数据库(实例)。我需要如何在这里定义它?

我在这里提供一个查询的例子

代码语言:javascript
代码运行次数:0
运行
复制
DECLARE @startDate DATETIME = CONVERT(DATE, GETDATE());
DECLARE @endDate DATETIME = CONVERT(DATE, GETDATE()+1);

DECLARE @stDate NVARCHAR(MAX) = CHAR(39) + CONVERT(NVARCHAR(255), @startDate, 23)+ CHAR(39) + ',';
DECLARE @enDate NVARCHAR(MAX) = CHAR(39) + CONVERT(NVARCHAR(255), @endDate, 23) + CHAR(39);
DECLARE @execCommand NVARCHAR(MAX) = CHAR(39) + 'EXEC dbo.getRecordsByOrderDate ' ;
DECLARE @concatCommand NVARCHAR(MAX) = @execCommand + @stDate + @enDate + CHAR(39);

DECLARE @opQuery Nvarchar(MAX) = 'Select * Into #Temp1 from Openquery(LOCALSERVER, '+ @concateCommand +') oq'

EXEC (@opQuery);

错误消息:

Msg 102,级别15,状态1,第20行语法不正确,接近'2020‘。

如果我尝试以以下格式执行

代码语言:javascript
代码运行次数:0
运行
复制
Select * Into #Temp1 from Openquery(LOCALSERVER, 'EXEC dbo.getRecordsByOrderDate ''2020-12-11'',''''2020-12-12''''') oq

Msg 11529、级别16、状态1、过程sys.sp_describe_first_result_set、第1批开始行31行元数据无法确定,因为每个代码路径都会导致错误;请参阅前面的错误。Msg 2812,级别16,状态62,过程sys.sp_describe_first_result_set,第1行批开始行31无法找到存储过程'dbo.getRecordsByOrderDate'.

EN

回答 1

Stack Overflow用户

发布于 2020-12-11 21:39:07

问题在于你没有转义注入参数的引号。调试动态代码的最简单方法是PRINT/SELECT。如果你这样做,你很快就会发现问题所在:

代码语言:javascript
代码运行次数:0
运行
复制
DECLARE @startDate DATETIME = CONVERT(DATE, GETDATE());
DECLARE @endDate DATETIME = CONVERT(DATE, GETDATE()+1);

DECLARE @stDate NVARCHAR(MAX) = CHAR(39) + CONVERT(NVARCHAR(255), @startDate, 23)+ CHAR(39) + ',';
DECLARE @enDate NVARCHAR(MAX) = CHAR(39) + CONVERT(NVARCHAR(255), @endDate, 23) + CHAR(39);
DECLARE @execCommand NVARCHAR(MAX) = CHAR(39) + 'EXEC dbo.getRecordsByOrderDate ' ;
DECLARE @concatCommand NVARCHAR(MAX) = @execCommand + @stDate + @enDate + CHAR(39);

DECLARE @opQuery Nvarchar(MAX) = 'Select * Into #Temp1 from Openquery(LOCALSERVER, '+ @concatCommand +') oq'

PRINT @opQuery;

还会回来..。

代码语言:javascript
代码运行次数:0
运行
复制
Select *
Into #Temp1
from Openquery(LOCALSERVER, 'EXEC dbo.getRecordsByOrderDate '2020-12-11','2020-12-12'') oq

瞧,您的第一个参数转义了第二个参数,因此出现了错误。(我增加了额外的行,因为SO对“漂亮词”的选择认为#是SQL中的一个注释字符,我希望在着色中突出显示转义。)

当在文字字符串中使用单引号时,需要通过“加倍它们向上”('')来转义它们。因此,我需要在最后发言如下:

代码语言:javascript
代码运行次数:0
运行
复制
Select *
Into #Temp1
from Openquery(LOCALSERVER, 'EXEC dbo.getRecordsByOrderDate ''20201211'',''20201212''') oq

(再次添加用于表示的其他行。)

因此,您需要修复2个注入值的定义:

代码语言:javascript
代码运行次数:0
运行
复制
DECLARE @stDate NVARCHAR(8) = CHAR(39) + CHAR(39) + CONVERT(NVARCHAR(8), @startDate, 112)+ CHAR(39) + CHAR(39) + ',';
DECLARE @enDate NVARCHAR(8) = CHAR(39) + CHAR(39) + CONVERT(NVARCHAR(8), @endDate, 112) + CHAR(39) + CHAR(39);

注:我也更改了数据类型和样式。作为yyyy-MM-dd的样式在Server和数据类型中并不是明确的,因为一个日期不需要20亿个字符。

但是,请注意,在执行此操作之后,您仍然无法访问#Temp1。临时表只对其创建的作用域持续存在,而该作用域是动态SQL的。您需要在动态语句中使用一个永久表,或者在动态语句之外使用一个临时表以在其外部使用它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65258603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档