从选择语句中更新SQL

6

非常抱歉内容有些长,我试图提供尽可能多的信息以避免无关的解决方案。

我的目标是将至少1个UPDATE语句嵌入到SELECT语句中,这样我就有机会在执行SELECT语句之前更新一些计算值(类似于SELECT触发器)。VIEW并不是我立即需要的解决方案,因为我受限于我正在使用的系统(请参见以下内容)。

我正在定制一个第三方商业ERP,该系统功能较弱(系统名称不便透露!--总之您没有听说过它,但它也不是自制的)。它具有一个预制查询功能,我可以使用文本/GUI来构建SELECT查询。保存查询后,用户可以单击查询以执行它并查看结果。ERP运行在MS SQL Server 2000上;目前没有升级版本的计划。我可以在ERP外部使用任何语言编写所需的功能集,我以前已经这样做过,如果需要的话。但我的用户群体发现当我的定制可以在ERP系统中完成时更加容易。

查询可以是任意复杂的,但ERP软件包会自己构建SQL Select语句。编译后的ERP内部可能有类似于以下内容的东西(这只是猜测!):

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

GUI构建器可以帮助新手用户构建fieldList等内容,但只要SQL在合并时有效,您可以绕过它并以文本编写子句。
我似乎找不到运行存储过程的咒语作为SELECT语句的副作用,无论是在选择子句中还是在where子句中等。我真的不关心如何越狱系统--稳定的SQL注入攻击就可以了,只要它不意味着我必须修改基础SQL服务器的安全性。我看过UDF,但您不能将UPDATE语句放入标量UDF中,并且尝试修改表UDF的返回值是没有意义的(或者有吗?)。如果您可以从VIEW中进行UPDATE,那么我想看一个示例,但我意识到我可以使用VIEW来计算列,而这不是我要寻找的解决方案。我在网上读到了一个暗示性声明,称可以使用某种XP_来实现此目的,但是哪个XP_或如何做到这一点,我不知道。
这个问题本身不是一个解决方案:Updating a table within a select statement

FYI,进一步的研究表明,CLR函数可能会帮我实现目标,但是在SQL 2000中不可用。 - user130582
5个回答

1
我想不出任何方法将SELECT与UPDATE结合在SQL 2000中(尽管在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别名),而你想要的数据将在第二个集合中。其他解决方法可能是可能的,这取决于这三个值如何使用以及如何捕获错误。(让第一个查询生成一个错误,并希望更新和第二个查询通过?)


0

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

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

0

尝试在存储过程中使用动态SQL,就像上次回复中所述一样。

链接原作者以便其获得应得的荣誉,并希望对您有所帮助。

既然您想要在UPDATE之前进行SELECT,您可以修改动态SQL,如我发布的链接所示,先执行SELECT。


0

存储函数是一个选项吗?在MySQL中,您可以更无缝地调用它们而不是存储过程-- 您只需使用 "SELECT FUNCTION_NAME(x)" 而不是 "call PROCEDURE_NAME(x)"。


0

我猜测使用 XP 时,您需要编写自己的 XP 进行更新,并以某种方式将其包含在查询中。无论这是否有效,以及应该在查询中的哪个位置运行,使之在 SQL 查看您的数据之前运行,这都完全超出了我的能力范围。

听起来您已经尝试了我会尝试的所有方法。我感到为您难过,因为在运行选择操作之后更新状态可能相对容易一些。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接