【问题标题】:Using local variable for "IN" criteria condition with SQL Server [duplicate]使用 SQL Server 的“IN”条件条件的局部变量 [重复]
【发布时间】:2011-10-05 09:50:24
【问题描述】:

可能重复:
SQL : in clause in storedprocedure:how to pass values

我正在使用 MS SQL Server 2005,并尝试编写一个两步流程的脚本:

  1. 在表中查询符合特定条件的 ID 列表
  2. 更新该表中的字段,其中 ID 位于第一个返回的 ID 列表中

需要注意的是,步骤 1 和 2 可能会有相当长的时间延迟分开并在不同的会话中执行。 #2 中使用的 ID 列表本质上是历史数据:#1 在过去时间点返回的值。

我尝试做的是将#1 中的所有 ID 以“##、##、##、##”格式写入 varchar(8000)(这部分效果很好),然后使用该字符串:

UPDATE table SET field=newValue WHERE (id IN (@varcharOfCommaSeparatedIDs))

但这给了我一个语法错误,指出它无法将该 varchar 值转换为所需的值(错误消息被截断)

有没有办法在不将整个 SQL 命令放入字符串并执行该字符串的情况下执行此操作(使用 EXEC 或 sp_executesql)?经过多年避免注入攻击后,我对“动态 SQL”有些本能(也许是非理性的)厌恶

【问题讨论】:

  • 这是可行的,但解决方案要么是丑陋的黑客,要么太复杂。上周我在搜索这个时发现了一些关于 SO 的解释。
  • 您使用的语法无效,但是在将 CSV 数据传递到存储过程时可以使用一些技术。请注意,他们中的大多数人相当丑陋,但他们确实完成了工作。
  • @Kragen - 这不是骗子,因为他的要求是让列表在不同的过程/会话之间传递。
  • 克拉根说得对,这个问题已经足够接近回答我的问题了。这不是完全相同的场景,但我需要将第一步的结果以可以存储在 SQL 之外的格式(例如在应用程序中的字符串或结果集中)然后传递回#2(这限制了我稍后会使用字符串/varchar)。我可能应该在问题中明确说明该要求,我很抱歉没有这样做,并感谢所有回复的人......现在我如何将其标记为已回答/重复?

标签: sql sql-server-2005 criteria dynamic-sql


【解决方案1】:

把它写到一张桌子上。

IF EXISTS (SELECT 1 FROM Database.dbo.MyHoldingTable)
DROP TABLE Database.dbo.MyHoldingTable

SELECT <fields>
INTO Database.dbo.MyHoldingTable
FROM <other table>
WHERE <conditions>

然后,稍后:

UPDATE OtherTable
Set Column=NewValue
WHERE ID IN (SELECT id FROM Database.dbo.MyHoldingTable)

另外请注意,如果您愿意,也可以在您的桌子上使用 INNER JOIN 而不是 IN 子句。

【讨论】:

  • 我不能用用于这样的脚本的表来混淆这个生产环境:(
  • @Dave - 这并不混乱。将其放入WorkTable 数据库,完成后将其删除。如果您的要求是“制作一个列表,然后在另一个会话中的某个未指定时间或 proc 引用该列表”,您就是这样做的。
  • 还是使用临时表或表变量?但是如果可以避免的话,尽量不要将记录集存储为字符串。 (恕我直言)
  • 我们对 clutter 的定义不同 ;) 对于我正在处理的特定项目,从第 1 步返回的值列表根本无法存储在数据库中,脚本必须是非侵入性并在 SQL 之外进行任何长期存储。
  • @Dave - 然后将列表存储在您的应用程序层中。如果您使用相同的会话,您可以在需要时将日期存储在#temp 表中。
【解决方案2】:

如果您在 SQL Server 上的 SP 之间传递值,我强烈建议将值存储在表中...
- 临时表 (#mytable)
- 表变量 (@table)
- 真正的桌子

从 SQL Server 2008 开始,您可以使用表值输入参数...


如果您从应用程序中传递值,则可怕的逗号分隔字符串确实很有用。 SO上有很多答案提供表值函数,用于将字符串转换为id表,读取以加入。

SELECT
  *
FROM
  foo
INNER JOIN
  dbo.bar(@mystring) AS bar
    ON foo.id = bar.id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-03
    • 2013-07-20
    • 2013-07-23
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多