通过将参数作为查询传递来执行sql存储过程

时间:2013-07-04 06:41:57

标签: sql-server database sql-server-2012

我尝试了很多时间将查询作为参数传递给执行stored procedure。但它每次都会给出编译时错误。以下是我的query

exec IAM_INSERT_ASSET (select top 1 ItemID from MIR_ItemMaster order by ItemID desc),1662

有两个参数,其中第一个是查询动态的,第二个是硬编码的。 Obviously I can do this by keeping query in variable and passing variable.但我不想声明变量并将查询直接传递给过程。如何实现这一目标。有什么帮助吗?

5 个答案:

答案 0 :(得分:1)

您可以在EXEC语句中提供的所有 1 都是文字或变量。以下是EXEC的文档语法:

[ { EXEC | EXECUTE } ]
    { 
      [ @return_status = ]
      { module_name [ ;number ] | @module_name_var } 
        [ [ @parameter = ] { value 
                           | @variable [ OUTPUT ] 
                           | [ DEFAULT ] 
                           }
        ]
      [ ,...n ]
      [ WITH <execute_option> [ ,...n ] ]
    }
[;]

就是这样。所以你必须走可变路线。


1 您还可以使用少数内置函数,例如@@IDENTITY,它曾经是一个“全局变量”,但它非常很多例外而不是规则。

答案 1 :(得分:1)

@eraj
我得到你的基本查询 但是,我不认为它可以按照您想要的方式完成,即将查询作为参数传递。 这可以通过两种方式完成。

1)用这个SELECT写一个光标并从光标内执行SP。

DECLARE @p1 varchar(800);
DECLARE @p2 varchar(800);
DECLARE @p3 varchar(800);

DECLARE SP_Cursor CURSOR
    FOR SELECT p1,p2,p3
        FROM ..

OPEN SP_Cursor;

FETCH NEXT FROM SP_Cursor INTO @p1, @p2, @p3;

WHILE (@@FETCH_STATUS <> -1)  
BEGIN  
    EXEC SP_Name @p1,@p2,@p3;  
    FETCH NEXT FROM SP_Cursor INTO @p1, @p2, @p3;  
END  

CLOSE SP_Cursor;

DEALLOCATE SP_Cursor;

正如我所说,由于你的查询返回1000行,所以这会很慢,SP每次都会执行1000次连接数据库。
通过将数据集放入#temp_table并循环遍历WHILE循环,可以稍微提高性能。它每次至少会切断连接到数据库。

2)第二个选项是通过SELECT查询构建执行语句。

declare @execstatementsbatch nvarchar(max)
select @execstatementsbatch = ''

SELECT @execstatementsbatch = @execstatementsbatch   + 'EXEC SP_Name' + p1 +  ', '  + p2 +  ', '  + p3 + '; ' 
FROM..
<some conditions>

exec(@execstatementsbatch)

但是请注意,如果您处理大量数据,两者都不是很有效。


答案 2 :(得分:0)

为什么不将第一个参数定义为varchar并将查询作为字符串传递? 它基本上看起来像,

exec IAM_INSERT_ASSET 'select top 1 ItemID from MIR_ItemMaster order by ItemID desc',1662

答案 3 :(得分:0)

首先,我现在还没有访问SQL Server,所以这可能无法正常工作。

其次,我不明白为什么你不想使用变量 - 它是迄今为止最简单的解决方案。如果您构建的存储过程太聪明 - 例如根据第一个参数的值,IAM_INSERT_ASSET的行为会有所不同,我建议你重新考虑一下。从架构的角度来看,存储过程很难测试,难以调试和难以理解,因此您最终会通过明显不相关的更改(例如,向表中添加列)来破坏存储过程。

最后,如果您真的想这样做,可以使用dynamic SQL。如果将第一个参数更改为varchar,然后使用sp_executeSQL执行该varchar的内容,则可以传入任何所需内容。警告 - 我不知道这是否有效,无法尝试。其他警告 - 这可能会使您的系统变得脆弱并以令人兴奋的方式失败。

答案 4 :(得分:0)

也许这会有用吗?

declare @docnumber2 char(21) -- or whatever the field is varchar,int,etc.
set @docnumber2 = (select top 1 docnumber from invoices order by doc_timestamp)
exec udsp_blahblah @docnumber2
相关问题