我带有 2 个 INSERT 命令的 SQL 语句在第二个 INSERT 上失败

My SQL statement with 2 INSERT commands is failing on the second INSERT

提问人:SkyeBoniwell 提问时间:8/16/2023 最后编辑:Mark RotteveelSkyeBoniwell 更新时间:9/14/2023 访问量:85

问:

我有以下两点说法:INSERT

-- Create a new database entry for the astronomicalObject in the GradObservers database
-- based on values of the given id
INSERT INTO astro.bodies (id, title, coordinates) 
    SELECT NEXT VALUE FOR bodies.nextid, title, 9291
    FROM astro.astro 
    WHERE id = 002811

-- Insert new id from table above into astro.sources
-- Insert other fields from existing bodyId 002811
INSERT INTO astro.sources(bodyId, baseValue, Url)
    (SELECT CONVERT(BIGINT, current_value) FROM sys.sequences WHERE schema_id = 71)
    SELECT baseValue, Url 
    FROM astro.sources 
    WHERE bodyId = 002811

我正在尝试执行 2 个命令,其中第二个命令取决于第一个命令的值。INSERTID

第一个使用数据库中的 a 来获取它的 .INSERTSEQUENCEID

然后第二个也需要使用该 ID。INSERT

第一个有效,但我从第二个语句中得到一个错误:INSERT

INSERT 语句的选择列表包含的项少于插入列表。SELECT 值的数目必须与 INSERT 列数匹配。

有没有办法做到这一点?

sql-server sql-server-2008

评论

3赞 Stu 8/16/2023
您的第二个插入是语法错误,它应该是INSERT INTO astro.sources(bodyId, baseValue, Url) select(SELECT CONVERT(BIGINT, current_value) FROM sys.sequences WHERE schema_id = 71), baseValue, Url FROM astro.sources WHERE bodyId = 002811
1赞 Stu 8/16/2023
您可以尝试一下,看看 - 目前您正在插入一个值,后跟一个单独的 select 语句......
2赞 marc_s 8/16/2023
顺便说一句:SQL Server 2008 和 2008 R2 现在完全不受支持(甚至超出了扩展支持) - red-gate.com/simple-talk/sql/database-administration/... - 是时候升级了!
2赞 Thom A 8/16/2023
仅供参考,SQL Server 2008 在 4 年前完全不受支持,您现在真的应该升级您的实例。使用这样一个古老的理由会带来大量的安全问题,并且是不负责任的。
1赞 Thom A 8/16/2023
虽然你使用的方法并不安全,但它可能会受到竞争条件的影响。为什么不在第一个语句中使用子句来获取生成值呢?OUTPUTINSERTSEQUENCE

答:

2赞 Charlieface 8/16/2023 #1

要插入一个值,后跟一个单独的语句。SELECT

正确的语法是将 嵌套在 main 中。为了安全起见,您可能应该使用序列名称。SELECTSELECT

INSERT INTO astro.sources
  (bodyId, baseValue, Url)
SELECT
  (
    SELECT CONVERT(BIGINT, seq.current_value)
    FROM sys.sequences seq
    JOIN sys.schemas sch ON sch.schema_id = seq.schema_id
    WHERE sch.name = 'bodies'
      AND seq.name = 'nextid'
  ),
  baseValue,
  Url 
FROM astro.sources 
WHERE bodyId = 002811;

但是,最好首先将其存储在变量中。

DECLARE @id bigint = NEXT VALUE FOR bodies.nextid;

INSERT INTO astro.bodies
  (id, title, coordinates) 
SELECT
  @id,
  title,
  9291
FROM astro.astro 
WHERE id = 2811;

INSERT INTO astro.sources
  (bodyId, baseValue, Url)
SELECT
  @id,
  baseValue,
  Url 
FROM astro.sources 
WHERE bodyId = 2811;

旁注:没有多大意义。 是一个数字而不是一个字符串,那么为什么它有前导零。bodyId = 002811002811