【问题标题】:can I nest insert t-sql inside an update t-sql?我可以在更新 t-sql 中嵌套插入 t-sql 吗?
【发布时间】:2014-05-28 19:37:35
【问题描述】:

是否可以在更新语句中嵌套插入语句?

背景

我第一次使用merge 子句来转换一些数据。也就是说,我有一个包含许多列的单一源表,但如果缺少更好的词,我需要 转换 到更结构化的模型/模式;类似于BI 模型。我在 BI 建模方面也缺乏经验(现在才开始阅读它不到一个月)。任何帮助都会很大 赞赏。

我很乐意提供可能需要帮助的任何其他信息。

错误:

消息 156,第 15 级,状态 1,第 47 行
关键字“select”附近的语法不正确。

消息 102,第 15 级,状态 1,第 48 行
')' 附近的语法不正确。

这些是在我尝试执行 insert into tertiary.WEBADDRESS 行时抛出的。

代码:

--Transform operation
--web address dimension insert
use UniversityUS
merge tertiary.INSTITUTION as target
using(
        select UNITID,
             INSTNM,
             ADDR,
             CITY,
             STABBR,
             ZIP,
             OBEREG,
             WEBADDR,
             ADMINURL,
             FAIDURL,
             APPLURL,
             HLOFFER,
             GENTELE,
             LOCALE,
             CARNEGIE,
             FAXTELE,
             IALIAS,
             F1SYSNAM,
             COUNTYNM,
             LONGITUD,
             LATITUDE
             --geography::Point(LATITUDE,LONGITUD,4326)) as [LOCATION]
        from staging.secondary_university
        where closedat = -2
    ) as source
on ( source.UNITID = target.ROWSOURCECONTROLID )
when not matched by target then

        --this would represent my fact table
        insert (INSTNM,IALIAS,GENTELE,F1SYSNAM,ROWSOURCECONTROLID)
        values (source.INSTNM,source.IALIAS,source.GENTELE,source.F1SYSNAM,source.UNITID)       

when matched then

        update set target._WEBADDRID = 
        (
            select wa.wid
            from
            (
                --this would represent one of my many dimension tables
                --if i comment the next two lines it works
                --but i need to know how will these be updated.
                insert into tertiary.WEBADDRESS 
                values(source.WEBADDR,source.ADMINURL,source.FAIDURL,source.APPLURL)

                select scope_identity() as wid
            )wa 
        )

when not matched by source then
    delete
output $action;

【问题讨论】:

  • @AaronBertrand - 现在我正在努力找出如何进行转换(BI 的新手)?哈哈....很高兴你早早地向我指出了这一点。我注意到的一件事是它没有将所有行都插入到新表中。我不完全确定这个问题,但同时会考虑分离陈述。谢谢。

标签: sql-server-2008 tsql sql-merge


【解决方案1】:

我知道这是一个老问题,但它是一个有趣的问题,所以我会尽我所能为任何可能在研究自己的好奇心时偶然发现它的人回答。

我首先要说这可能是一种不好的做法。通过尝试嵌套这样的语句,您会冒着无法阅读代码的风险,如果出现一些并发问题,我也不会太惊讶。但是,如果您对此完全满意,您可能可以使用存储过程完成类似的事情。但同样,像这样不清楚的副作用可能是不可读的。您还可以查看该插入的 OUTPUT 子句。我不确定,但您可以添加OUTPUT INSERTED.ID(或任何您的身份列名称)并针对它运行您的选择,而不是使用插入后跟选择是有道理的。同样,我不确定这是否可行。但这听起来很合理。

总而言之,正如 Aaron 在他的评论中提到的那样,最好将其分成几个单独的操作。我个人对MERGE 没意见,我已经使用过它,它还没有给我带来该帖子中警告的任何问题,尽管它们现在也可能是旧消息,因为我们有几个版本。但是我至少建议您将插入内容提取到单独的甚至事务共享语句中:

INSERT INTO tertiary.WEBADDRESS 
SELECT WEBADDR, ADMINURL, FAIDURL, APPLURL
    FROM staging.secondary_university
    WHERE closedat = -2 AND
          EXISTS (SELECT *
                  FROM tertiary.INSTITUTION
                  WHERE tertiary.Institution.ROWSOURCECONTROLID = staging.secondary_university.UNITID)

然后,您可以轻松地修改您的 WHEN MATCHED 子句以获取适当的身份值,给定您需要建立唯一性的任何键。

 ...
 WHEN MATCHED THEN
      UPDATE SET target._WEBADDRID = (SELECT TOP 1 [whatever_your_ID_column_is]
                                      FROM staging.secondary_university
                                      WHERE staging.secondary_university.WebAddr = source.WebAddr AND
                                            staging.secondary_university.ADMINURL = source.ADMINURL AND
                                            staging.secondary_university.FAIDURL = source.FAIDURL AND
                                            staging.secondary_university.APPLURL = source.APPLURL)
 ...

【讨论】:

    猜你喜欢
    • 2011-01-17
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 2021-09-30
    相关资源
    最近更新 更多