【问题标题】:SQL Query Error 1087 in Stored Procedure but works fine outside the procedure存储过程中的 SQL 查询错误 1087,但在过程之外工作正常
【发布时间】:2020-07-31 21:33:49
【问题描述】:

我正在使用调用者的这个存储过程来验证结果。 我从基于用户定义的表类型的表中获取值。 错误是通过 exec-command 引起的,因为没有它都可以通过。

失败:

ALTER PROCEDURE [cam].[M0017TEST]
@dealRecords cam.dealDataRecords readonly,
@ruleParams cam.validationRuleParams readonly
    AS
    SET NOCOUNT ON;
    BEGIN
declare @result as cam.validationRuleResult;
declare @Status as int = 0
declare @Kaktion NVARCHAR(50)  = (select Val from @ruleParams where Name = 'Source')
declare @KAWert NVARCHAR(50) = (select Val from @ruleParams where Name = 'Equ')
declare @KA NVARCHAR(200)
declare @knr bigint = (select ID from @dealRecords)
declare @vi NVARCHAR(50)
DECLARE @vQuery NVARCHAR(150)
    
if @Kaktion <> ''
    Begin
        set @vQuery = concat('select @vi=',@Kaktion,' from @dealRecords'); 
        -- SQL String is fine
        EXEC SP_EXECUTESQL  
            @Query  = @vQuery
            , @Params = N'@vi Nvarchar(50) OUTPUT'
            , @vi = @vi OUTPUT

        set @KA = (SELECT @vi)
            ….

结果是错误 1087。

如果我在没有存储过程的情况下使用它,一切都很好,我会得到正确的结果。

工作正常:

'''

    declare @KontT table (Val varchar(30))
    DECLARE @vi int
    DECLARE @vQuery NVARCHAR(150)
    declare @Kontoaktion nvarchar(50) = 'has_Val'
    declare @KA nvarchar(50)

    insert into @KontT(Wert)
    values('ID')

    declare @ID varchar(20) = (select Val from @KontT)

    set @vQuery = N'select top(1) @vi=' + @ID + ' from cam.tbl_ListRegelPoolProduktcode 
                  where p1 like ' + NCHAR(39) + @Kontoaktion + NCHAR(39)
        EXEC SP_EXECUTESQL 
            @Query  = @vQuery
            , @Params = N'@vi int OUTPUT'
            , @vi = @vi OUTPUT
        set @KA = (SELECT @vi)

我尝试了很多套路。有变量,没有,有表格,没有 aso。但最后总是执行命令在存储过程中失败。

任何人都可以解释行为的区别或给我一个提示,我错在哪里?

【问题讨论】:

  • 您使用的是哪个 dbms?该代码是特定于产品的。
  • 如果您给出与该错误一起显示的确切消息会有所帮助,因为 1987 is particularly generic: "Cannot %S_MSG %S_MSG '%.*ls' on %S_MSG '%.*ls' 因为它%S_MSG 已禁用。”
  • 非常抱歉,这是错误 1087
  • 请复制错误信息 mate :) 为什么要我们查?
  • 这是我得到的错误信息。我阅读了系统错误代码并将其格式化为我的需要。错误 - 池 4 规则 20:从“M0017Action”调用失败:错误 1087 ID/Nr:99999/217745401

标签: sql-server tsql


【解决方案1】:

我相信@dealRecords 是一个只读表参数,不能转发给动态sql 查询。 (因为该查询可能会尝试更新表中的数据)。

您可以将其替换为临时表。 (要么从调用过程中创建它,要么在此 SP 中创建并在其中插入来自 @dealRecords 的数据)。我假设其中只有几行,因此性能影响不会很大。

*** 编辑:创建测试脚本后,我发现您可以发送表参数,但只需添加只读。因此,为您的动态查询添加一个参数:

, @Params = N'@vi Nvarchar(50) OUTPUT, @dealRecords cam.dealDataRecords readonly'
, @vi = @vi OUTPUT,  @dealRecords = @dealRecords 

这能解决您的问题吗?

【讨论】:

  • 为什么要从只读表中“选择”输出存储在变量中的原因(变量中的值是正确的)?我不转发表格,我转发变量。我已经用 temptable 和 tablevariable 试过了。还是不行。
  • 检查我编辑的关于缺少参数的答案。
  • 是的,就是这样。罗得是树林里的一棵树。
猜你喜欢
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
相关资源
最近更新 更多