从 select 语句更新 SQL
抱歉,这篇文章太长了,我试图提供大量信息以避免不相关的解决方案。
我的目标是在 SELECT 语句中嵌入至少 1 个 UPDATE 语句,以便我有机会在 select 语句运行之前更新一些计算值(将其视为 SELECT 上的 TRIGGER)。 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 语句的副作用,无论它是在 select 子句、where 子句等中。我真的不在乎我如何越狱系统 - 一个稳定的系统SQL注入攻击没问题,只要它不意味着我必须修改底层sql服务器本身的安全性。 我已经研究过 UDF,但是您不能将 UPDATE 语句放入标量 UDF 中,并且尝试修改表 UDF 的返回没有意义(或者确实如此?)。 如果您可以从视图中更新,那么我想看一个示例,但我意识到我可以使用视图来计算列,但这不是我正在寻找的解决方案。 我在网上读到一个关于能够使用某种 XP_ 来完成此操作的暗示性声明,但至于使用哪种 XP_ 或如何做到这一点,我不知道。
这个问题本身并不是一个解决方案: Updating a table inside a select声明
Sorry for the length of this, I'm trying to give a lot of info to avoid non-relevant solutions.
My goal is to embed at least 1 UPDATE statement into a SELECT statement so that I have a chance to update some computed values at the instant before the select statement runs (think of it like a TRIGGER on SELECT). VIEW is not in immediate solution, since I'm constrained by the system I'm using (see below).
I'm customizing a 3rd party commerical ERP that is weak on features (system will remain nameless! -- upshot is you haven't heard of it, but its not home grown either). It has a canned query facility where I can use a text/GUI to build a SELECT query. Once I save a query, the users can click on the query to execute it and see the results. ERP runs atop MS SQL Server 2000; version upgrade is NOT in the cards right now. I can write whatever feature set I need outside of the ERP in whatever language I want, I have done this in the past, if the features warrant it. But my user community finds it easier when my customizations can be done in the ERP system.
The query can be arbitrarily complex, but the ERP package builds the SQL Select statement itself. Internal to the compiled ERP is something like this (this is just a guess!):
"SELECT " + fieldList + " FROM " + tableListAndJoins + " WHERE " + whereCond
The GUI builder helps novice users build the fieldList and so on but you can bypass it and write the clauses in text as long as the SQL is valid when combined as above.
I can't seem to find an incantation to run a stored procedure as a side effect of a SELECT statement, whether it's in the select clause, where clause, etc. I really don't care how I jailbreak the system -- a stable SQL injection attack would be fine, as long as it didn't mean I had to modify the security of underlying sql server itself. I've looked at UDFs, but you can't put an UPDATE statement into a scalar UDF, and it doesn't make sense to try to modify the return of a table UDF (or does it?). If you can UPDATE from within a VIEW then I would like to see an example, but I realize I can use a VIEW to compute columns and that is not the solution I am looking for. I read a suggestive statement online about being able to use some sort of XP_ to accomplish this, but as to which XP_ or how to do it, I don't know.
this question is NOT a solution, in and of itself: Updating a table within a select statement
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我想不出在 SQL 2000 中将 SELECT 与 UPDATE 结合起来的任何方法(尽管在 2005 年及更高版本中,OUTPUT 子句可用)。 然而,看起来你得到了三个字符串值(fieldList、tableListAndJoins、whereCond),它们与“SELECT”、“FROM”和“WHERE”连接在一起,并假设它们没有进行一些严格的类似 SQL 注入的代码检测,你也许可以把这样的东西拼凑在一起:
[分号实际上是可选的,甚至可能在 SQL 2000 中不起作用——它们只是清楚地表明一个命令在哪里结束,下一个命令在哪里开始。]
这样做的缺点是你将返回两个数据集。 第一个将是一个空的单列集(如果您想要为列命名,则别名为 NULL),并且您想要的数据将位于第二个集中。 可能还有其他解决方法,具体取决于如何使用这三个值以及如何捕获错误。 (让第一个查询生成并出错,并希望更新和第二个查询能够通过?)
I can't think of any way to combine a SELECT with an UPDATE in SQL 2000 (though in 2005 and up, the OUTPUT clause is available). However, it looks like you get three string values (fieldList, tableListAndJoins, whereCond) that get concatenated together with "SELECT", "FROM" and "WHERE", and assuming they don't do some serious SQL injenction-like code detection, you might be able to kludge together something like this:
[The semicolons are actually optional, and might not even work in SQL 2000 -- they just make it clear where one command ends and the next begins.]
The downside of this is that you'll get back two data sets. The first will be an empty one-column set (alias that NULL if you want a name to the column), and the data you want will be in the second set. Other work-arounds might be possible, depending on how these three values are used and how errors are caught. (Let that first query generate and error, and hope the update and the second query go through?)
尝试在存储过程中使用动态sql,如在此处最后一个回复中所述
链接,以便原作者可以获得他/她应得的学分,希望对您有所帮助。
由于您希望在 UPDATE 之前进行 SELECT,因此您可以按照我发布的链接修改动态 sql,首先执行 SELECT。
Try using dynamic sql in the stored procedure as stated on the last reply here
Linked so that the original author can get the credits he/she deserves, and hopefully will be helpful to you.
And since you want SELECT before the UPDATE, you can modify the dynamic sql as in the link I posted, to do the SELECT first.
我不确定我是否理解您情况的限制,但是您是否不能同时运行两个语句,例如:
I am not sure I understand the constraints of your situation, but can you not just run two statements at once, such as:
可以选择存储函数吗? 与存储过程相比,您可以更无缝地调用这些过程(至少在 MySQL 中)——您可以只使用“SELECT FUNCTION_NAME(x)”,而不是“call PROCEDURE_NAME(x)”。
Would a stored function be an option? You can call those more seamlessly (in MySQL at least) than stored procedures -- instead of "call PROCEDURE_NAME(x)" you can just use "SELECT FUNCTION_NAME(x)".
我对 XP 的猜测是,您将编写自己的 XP 来进行更新,并以某种方式将其包含在查询中。 这是否可行以及它应该在查询中的什么位置以便在 SQL 查看您的数据之前运行完全超出了我的范围。
听起来你几乎已经尝试了我会尝试的一切。 我对你有同样的感觉,因为在你运行选择之后更新状态可能会相当容易。
My guess with the XP is that you would write your own XP to do the update and include it in the query somehow. Whether or not that would work and where in the query it should go so as to be run before SQL looks at your data is completely beyond me.
It sounds like you've tried just about everything I would try. I feel for you because it'd probably be rather easy to update the state after you ran the select.