【问题标题】:I want to pass parameter select query in sql server storedprocedure我想在 sql server 存储过程中传递参数选择查询
【发布时间】:2018-10-25 07:21:02
【问题描述】:

这是我的查询:

declare @process varchar(50) ,@id int
set @id=11
set @process='PRODUCTION'

update Tracking 
set TargetbyHour = (
    (
        select cast(replace(costbyhour, '.','')/1 as integer) 
        from Tracking 
        where  trackingid = @TrackingID
    ) /    
    (
        (select   @process 
         from [dbo].[BillingSheet] 
         where  id=@id
        )
    )  
)    
where  TrackingID=@TrackingID

这是错误:

消息 245,第 16 级,状态 1,第 26 行 将 varchar 值“PRODUCTION”转换为数据类型 int 时转换失败。

注意:PRODUCTION是表列名数据类型是float

【问题讨论】:

  • 如果我手动输入 PRODUCTION,它可以工作,但我只想传递参数
  • 不,@process 是一个varchar(50),你碰巧设置为字符串'PRODUCTION',当你Select @process 你得到varchar(50)。
  • 在编写基于注入字符串生成任意 TSQL 的存储过程之前,我建议阅读此参考资料sommarskog.se/dynamic_sql.html
  • 根本不需要使用动态SQL。你可以UNPIVOT[dbo].[BillingSheet] 然后你可以使用WHERE 过滤掉'PRODUCTION' 行。

标签: sql sql-server tsql


【解决方案1】:

你不能在 SQL 中参数化标识符 - 所以

select   @process 
from [dbo].[BillingSheet] 
where  id=@id

将简单地返回存储在 @process 变量中的值 - 在这种情况下 - 'PRODUCTION'

如果您有多个具有相同数据类型的列,并且您想选择从哪一列中选择,您可以使用案例:

select case @process
       when 'PRODUCTION' then PRODUCTION
       when 'TEST' then TEST
       when 'DEV' then DEV
       end As val
from [dbo].[BillingSheet] 
where  id=@id

请注意,case 表达式必须从它的所有分支返回相同的数据类型,因此如果列具有不同的数据类型,您必须将它们转换为最适合您需要的数据类型。

【讨论】:

    【解决方案2】:

    你需要构建动态sql并执行。

    declare @process varchar(50) ,@id int, @TrackingID INT
    set @id=11
    set @process='PRODUCTION'
    
    DECLARE @SqlText  nvarchar(max)
    SET @SqlText  = 'update Tracking 
    set TargetbyHour = (
        (
            select cast(replace(costbyhour, ''.'','''')/1 as integer) 
            from Tracking 
            where  trackingid = @TrackingID
        ) /    
        (
            (select  ' + QUOTENAME(@process) + '
             from [dbo].[BillingSheet] 
             where  id=@id
            )
        )  
    )    
    where  TrackingID=@TrackingID'
    
    DECLARE @paramlist  nvarchar(max)
    SET @paramlist  = '@TrackingID INT,
                    @id INT'
    
    
    EXEC sp_executesql @SqlText, @paramlist, 
                    @TrackingID ,
                    @id 
    

    【讨论】:

    • @ganesh 但我不会在存储过程中这样做,而是在调用代码中这样做。
    【解决方案3】:

    你不需要动态 SQL,看这个

    DECLARE @process VARCHAR(50) = 'PRODUCTION';
    DECLARE @id INT  = 11;
    DECLARE @cost FLOAT;
    
    SELECT
                @cost = [Cost]
        FROM
                (
                SELECT
                            [Id],
                            [PRODUCTION],
                            [DEV],
                            [TEST]
                    FROM
                            [dbo].[BillingSheet]
                ) P
            UNPIVOT
                (
                    [Cost] FOR [Process] IN ([PRODUCTION],[DEV],[TEST])
                ) UP
        WHERE
                [Id] = @Id
            AND
                [Process] = @process;
    
    UPDATE [Tracking] 
        SET
            [TargetbyHour] = CAST(REPLACE([costbyhour], '.','')/1 AS INT) / @cost
        FROM
                [Tracking] 
        WHERE
                [trackingid] = @TrackingID;
    

    这种方法UNPIVOTs [dbo].[BillingSheet] 因此可以使用普通的WHERE 提取'PRODUCTION' 值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多