【问题标题】:SQL update from select statement从 select 语句更新 SQL
【发布时间】:2010-11-06 18:42:29
【问题描述】:

对不起,这里的长度,我试图提供很多信息以避免不相关的解决方案。

我的目标是将至少 1 条 UPDATE 语句嵌入到 SELECT 语句中,这样我就有机会在 select 语句运行之前的那一刻更新一些计算值(把它想象成 SELECT 上的 TRIGGER)。 VIEW 没有立即解决,因为我受到我正在使用的系统的限制(见下文)。

我正在定制一个功能较弱的第 3 方商业 ERP(系统将保持无名!- 结果是您还没有听说过它,但它也不是本土开发的)。它有一个预设查询工具,我可以在其中使用文本/GUI 来构建 SELECT 查询。保存查询后,用户可以单击查询来执行它并查看结果。 ERP 在 MS SQL Server 2000 上运行;版本升级现在不在卡上。我可以用我想要的任何语言在 ERP 之外编写我需要的任何功能集,如果功能允许的话,我过去曾这样做过。但是当我的自定义可以在 ERP 系统中完成时,我的用户社区发现它更容易。

查询可以任意复杂,但 ERP 包会自行构建 SQL Select 语句。编译后的 ERP 内部是这样的(这只是一个猜测!):

"SELECT " + fieldList + " FROM " + tableListAndJoins + " WHERE " + whereCond

GUI builder 帮助新手用户构建 fieldList 等,但您可以绕过它并以文本形式编写子句,只要 SQL 在如上组合时有效。

我似乎找不到一个咒语来运行存储过程作为 SELECT 语句的副作用,无论是在 select 子句、where 子句等中。我真的不在乎我如何越狱系统 - - 一个稳定的 SQL 注入攻击就可以了,只要这并不意味着我必须修改底层 sql server 本身的安全性。我已经查看了 UDF,但是您不能将 UPDATE 语句放入标量 UDF,尝试修改表 UDF 的返回是没有意义的(或者是这样吗?)。如果您可以从 VIEW 中更新,那么我想看一个示例,但我意识到我可以使用 VIEW 来计算列,这不是我正在寻找的解决方案。我在网上阅读了关于能够使用某种 XP_ 来完成此任务的暗示性声明,但至于哪个 XP_ 或如何做到这一点,我不知道。

这个问题本身并不是一个解决方案:Updating a table within a select statement

【问题讨论】:

  • 仅供参考,另外的研究表明 CLR 函数可能会让我到达那里,但 CLR 函数在 SQL 2000 中不可用。

标签: sql-server select sql-update


【解决方案1】:

我想不出任何方法可以在 SQL 2000 中将 SELECT 与 UPDATE 结合起来(尽管在 2005 年及更高版本中,OUTPUT 子句可用)。但是,看起来你得到了三个字符串值(fieldList、tableListAndJoins、whereCond),它们与“SELECT”、“FROM”和“WHERE”连接在一起,并假设它们没有进行一些严重的类似于 SQL 注入的代码检测,你也许可以把这样的东西拼凑在一起:

fileList = "NULL where 1 = 0; UPDATE MyTable set MyColumn = 'Whatever' where SomeColumn = 'Criteria'; SELECT MyColumn"

tableListAndJoins = "MyTable"

whereCond = "SomeColumn = 'Criteria'"

[分号实际上是可选的,甚至可能在 SQL 2000 中不起作用——它们只是清楚地表明一个命令在哪里结束,下一个命令从哪里开始。]

这样做的缺点是您将返回两个数据集。第一个将是一个空的单列集合(如果您想要列的名称,则别名为 NULL),您想要的数据将在第二个集合中。其他变通方法可能是可能的,具体取决于这三个值的使用方式以及错误的捕获方式。 (让第一个查询生成并出错,并希望更新和第二个查询通过?)

【讨论】:

    【解决方案2】:

    我对 XP 的猜测是,您会编写自己的 XP 来进行更新并以某种方式将其包含在查询中。这是否可行以及它应该在查询中的哪个位置运行以便在 SQL 查看您的数据之前运行完全超出了我的范围。

    听起来您几乎尝试了我会尝试的所有方法。我对你有感觉,因为在你运行选择之后更新状态可能会相当容易

    【讨论】:

      【解决方案3】:

      可以选择存储函数吗?你可以比存储过程更无缝地调用它们(至少在 MySQL 中)——而不是“调用 PROCEDURE_NAME(x)”,你可以只使用“SELECT FUNCTION_NAME(x)”。

      【讨论】:

        【解决方案4】:

        我不确定我是否理解你的情况的限制,但你能不能一次运行两个语句,例如:

        string sql = "update MyTable set x=y;select x from MyTable;";
        

        【讨论】:

          【解决方案5】:

          尝试在存储过程中使用动态sql作为stated on the last reply here

          链接,以便原作者获得他/她应得的学分,希望对您有所帮助。

          由于您希望在 UPDATE 之前选择 SELECT,因此您可以修改我发布的链接中的动态 sql,先执行 SELECT。

          【讨论】:

            猜你喜欢
            • 2014-05-15
            • 1970-01-01
            • 2017-01-15
            • 1970-01-01
            • 1970-01-01
            • 2012-12-05
            • 2013-02-11
            • 2012-05-18
            • 2019-05-24
            相关资源
            最近更新 更多