【问题标题】:Execute sql stored procedure by passing parameters as a query通过将参数作为查询传递来执行sql存储过程
【发布时间】:2013-07-04 06:41:56
【问题描述】:

我多次尝试将查询作为参数传递给执行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. 但我不想声明变量并将查询直接传递给过程。这怎么可能实现。有什么帮助吗?

【问题讨论】:

  • 存储过程的数据类型有哪些?和ItemID一样吗?使用变量。运行该过程是一个语句,因此它不能有另一个语句。
  • 数据类型与参数相同
  • 你为什么不使用变量?我认为这是传递动态参数的方式。
  • @kitty :当然可以,但是有许多过程都有动态参数。所以我认为传递查询会很好。

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


【解决方案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,它曾经是一个“全局变量”,但它在很大程度上是例外而不是规则。

【讨论】:

    【解决方案2】:

    @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)
    

    但请注意,如果您处理大量数据,两者的性能都不是很好。


    【讨论】:

      【解决方案3】:

      首先,我现在无法访问 SQL Server,所以这可能行不通。

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

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 我的所有参数都是动态的。更改每个过程的输入参数的数据类型会比较麻烦
        【解决方案5】:

        也许这会起作用?

        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
        

        【讨论】:

          猜你喜欢
          • 2017-12-29
          • 2014-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-18
          相关资源
          最近更新 更多