【问题标题】:What's the most efficient way to declare multiple values for a parameter? [closed]为参数声明多个值的最有效方法是什么? [关闭]
【发布时间】:2022-10-21 22:29:59
【问题描述】:

我正在运行一个批量更新脚本,其中 @masterNameID 在 (21,22,23) 中,但是当我运行这个 sn-p 时出现语法错误;

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE
@MasterNameID AS INT in (21,22,23)
,@RowCount AS INT

我尝试使用下面的方法声明一个临时表,但仍然无法运行;

Declare @MasterNameTlb table (MasterNameID INT (5))
 Insert into @MasterNameTlb (MasterNameID) values (21,22,23)
  Set @MasterNameID AS INT = select MasterNameID from @MasterNameTlb

关于如何让它运行或者是否有更有效的方法来为更新脚本声明多个值的任何想法?

**编辑:

抱歉,我在这里要做的是修改一个更新脚本,该脚本将以 20k 为单位进行更新,其中值在 (21,22,23) 中。尝试“in (21,22,23)”时出现语法错误。我还尝试创建一个临时表以从中提取值,但仍然出现错误。任何帮助,将不胜感激。

完整的原始脚本:

PRINT 'Shell_Index.SQL BEGIN'
If Object_ID('tempdb..#temp') Is Not Null
    DROP Table #temp
GO

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE
@MasterNameID AS INT 
,@RowCount AS INT
DECLARE @Begin int
DECLARE @End int
DECLARE @Buffer int
DECLARE @MaxRec INT
SELECT
    et.ESTrackLogID
    ,et.ESFlagSync
    ,ROW_NUMBER() OVER (ORDER BY et.ESTrackLogID) AS rn
    INTO #temp
FROM
      tbl1.ESTrackLog AS et
    JOIN tbl2  AS c ON c.ContactID = et.ESContactID
WHERE
   et.MasterNameID = @MasterNameID
    SELECT @RowCount = @@Rowcount
     print Cast(@RowCount as nvarchar) + ' row(s) inserted into #temp'
SELECT @Begin = min(rn) from #temp
SELECT @MaxRec = max(rn) from #temp
SELECT @Buffer = 20000
SELECT @End = @Buffer
WHILE @Begin <= @MaxRec
BEGIN
    BEGIN TRAN;
    UPDATE
        et
    SET
        et.ESFlagSync = 1
    FROM
        tbl1.ESTrackLog AS et
        JOIN #Temp                 AS a ON a.ESTrackLogID = et.ESTrackLogID
    WHERE
      et.MasterNameID = @MasterNameID
        AND a.rn BETWEEN @Begin and @End
    SELECT @RowCount = @@Rowcount
     print Cast(@RowCount as nvarchar) + ' row(s) updated in ESTrackLog'
    COMMIT TRAN
    if @RowCount > 0
    BEGIN
        WAITFOR delay '00:00:01';
    END
    SET @Begin = @End + 1
    SET @End = @End + @Buffer
END
PRINT 'Shell_Index.SQL DONE'

【问题讨论】:

  • @MasterNameID 是一个 int 这是一个标量值,它不能持有多个值。您实际上想在这里实现什么,因为上述尝试显然是XY Problem 的一部分。
  • “声明@MasterNameTlb 表(MasterNameID INT (5))”这会产生语法错误,int 在 SQL Server 中没有精度/比例参数。
  • 你打算用这个变量做什么?
  • READ UNCOMMITTED 忘记这个,忘记你曾经知道它的存在。这是一个坏主意,会导致许多并发问题,而且几乎从不需要。

标签: sql sql-server


【解决方案1】:

看起来您正在尝试将多个值插入到表变量中。正确的语法是:

Declare @MasterNameTlb table (MasterNameID INT);  -- use primary key?
Insert into @MasterNameTlb (MasterNameID) values (21),(22),(23);

select MasterNameID
from @MasterNameTlb AS t;

目前还不清楚你想要什么使用这张桌子,但您可以像其他任何人一样加入它。

【讨论】:

    【解决方案2】:

    试试这些:

    DROP TABLE IF EXISTS [#MasterName];
    GO
    -- Example 1 into a TEMP table
    Select [MasterName].[ID] INTO [#MasterName] FROM ( VALUES (21),(22),(23) )[MasterName]([ID]);
    Select [TBL]= '[#MasterName]', * from [#MasterName];
    -- Example 2 into a DECLARE table
    Declare @MasterName TABLE ([ID] INT);
    INSERT INTO @MasterName([ID])
    Select [MasterName].[ID] FROM ( VALUES (21),(22),(23) )[MasterName]([ID]);
    Select [TBL]= '@MasterName', * from @MasterName;
    

    【讨论】:

      【解决方案3】:

      您是否尝试更新其他一些表(此处未显示),其中值位于 (21,22,23) 中?您的临时表想法可能会奏效。创建临时表后,您将执行如下更新:

      update mytable
      set somecolumn = somevalue 
      where somekey in (
          select * from @MasterNameTlb
      );
      

      如果这不是您想要做的,也许可以在问题中添加更多细节。

      【讨论】:

      • IS IN 不是有效的语法,它只是 IN。此外,使用IN 对抗SELECT * 也不是一个好主意。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多