【问题标题】:SQL update in a select statement选择语句中的 SQL 更新
【发布时间】:2016-04-24 14:40:28
【问题描述】:

我的问题是:我需要从我的数据库中选择所有包含 NrPad 列的数据库表,而对于这些表,我需要更新 NrPad 列

我已经有一个有效的选择和更新语句:

select
    t.name as table_name
from sys.tables t
inner join sys.columns c
on t.object_id = c.object_id
where c.name like 'NrPad'

Update Anlage Set NrPad = CASE WHEN Len(Nr) < 10 THEN '0' + Convert(Nvarchar,Len(Nr)) ELSE Convert(Nvarchar,Len(Nr)) END + Nr

我的问题是:如何将这两个语句合并在一起?

我愿意接受建议,非常感谢您的帮助。

【问题讨论】:

  • 你没有说你正在使用什么 dbms,如果它的 oracle 比你的问题的答案是你的问题,你有 MERGE 语句可以通过另一个表更新一个表或在你的情况下选择
  • 更新所有表中的NrPad 以添加另一个0?您需要一个游标并使用动态 SQL 创建 UPDATE。
  • 就像 dnoeth 说的游标是唯一的解决方案,oracle 合并语句只是由另一个表更新而不是更新多个表

标签: sql sql-server select sql-update


【解决方案1】:

您的情况不是 testet,但您可以从哪里进行更新 - 设置 - 设置。

看看这个问题有多个答案:How do I UPDATE from a SELECT in SQL Server?

【讨论】:

    【解决方案2】:

    也许有人会评判我,但我能做的就是光标

        DECLARE @table_name varchar(100)
        DECLARE @sql varchar(1000)
        DECLARE table_cursor CURSOR FOR 
         select
           t.name as table_name
         from sys.tables t
         inner join sys.columns c
                 on t.object_id = c.object_id
              where c.name like 'NrPad'
       OPEN table_cursor
       Fetch next From table_cursor Into @table_name
        While @@fetch_status=0     
       Begin
         set @sql = 'Update' + @table_name + 'Set NrPad = CASE WHEN Len(Nr) < 10 THEN '0' + Convert(Nvarchar,Len(Nr)) 
                            ELSE Convert(Nvarchar,Len(Nr)) END + Nr'
         EXEC (@sql)
       Fetch Next From table_cursor Into @table_name
       End   
       Close table_cursor   
       Deallocate table_cursor
    

    这就是您在 SQLSERVER 中编写游标的方式,我真的不想为 Oracle 编写另一个游标。所以请标记你下次使用的dbms

    【讨论】:

    • 对不起,我完全忘记了我正在使用的 dbms - 它是 Microsoft SQLServer 2014。感谢您使用光标的解决方案。唯一的问题是,我不能使用表名作为变量(对吗?)。我尝试了您的解决方案,唯一的问题是更新后的@table_name“必须声明表变量“@table_name”。
    • 哦,不使用动态SQL是我的错,我编辑了答案并测试了它,会好的。你可以再试一次@user1474960
    • @user1474960 很高兴如果你能接受它的帮助:)
    【解决方案3】:

    您可以修改选择语句以生成更新语句,然后将它们全部执行。

    下面使用Oracle的字符串字面量。

    select 'Update ' || t.name || q'[ Set NrPad = CASE WHEN Len(Nr) < 10 THEN '0' + Convert(Nvarchar,Len(Nr)) ELSE Convert(Nvarchar,Len(Nr)) END + Nr;]'
    from sys.tables t
    inner join sys.columns c
    on t.object_id = c.object_id
    where c.name like 'NrPad' 
    

    【讨论】:

      【解决方案4】:

      使用INFORMATION_SCHEMA 而不是sys.tables,并像这样创建动态SQL 语句:

      DECLARE @sql varchar(max) = '';
      
      SELECT
          @sql = @sql + '; UPDATE ' + c.TABLE_NAME + ' SET NrPAd = CASE WHEN LEN(Nr)<10 THEN ''0'' + CONVERT(NVARCHAR,LEN(NR)) ELSE CONVERT(NVARCHAR,LEN(NR)) END + Nr'
      FROM INFORMATION_SCHEMA.COLUMNS c
      where c.COLUMN_NAME = 'NrPad'
      
      
      print @sql -- for debugging purposes
      exec (@sql)
      

      这假定所有具有NrPad 列的表也具有Nr 列。如果您需要检查这些,或者如果您只需要使用特定表中的 Nr 列,则有点不同(再次加入 INFORMATION_SCHEMA.COLUMNS 或加入 Anglage 以获取 Nr 的值或检查Nr 是该表上的一列)。

      【讨论】:

      • 没有问题 - 如果您发现它有帮助,请考虑将其标记为已接受的答案(投票摇杆下方的检查)。
      猜你喜欢
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 2012-09-10
      相关资源
      最近更新 更多