简体   繁体   English

根据表数据有条件地执行SQ​​L查询/语句

[英]Execute a SQL query/statement conditionally based on table data

First, take a look at this table, basically I need to UPDATE (+1) a ticket WHERE the Username equals to Jondoe AND Money is greater than 200. 首先,看看这个表,基本上我需要UPDATE(+1)一个票据,其中Username等于Jondoe和Money大于200。

在此输入图像描述

Now, I know I can execute 3 queries, first to check if the actual user has Jondoe as Username, then check if he has enough Money and if these results are true, then UPDATE (+1) a ticket finally. 现在,我知道我可以执行3个查询,首先检查实际用户是否将Jondoe作为用户名,然后检查他是否有足够的资金,如果这些结果为真,则最后更新(+1)一张票。

I'm learning SQL and i'm working over a mssql database, what's the proper way to do such a conditional query/update? 我正在学习SQL,而且我正在研究一个mssql数据库,这种条件查询/更新的正确方法是什么? Can I avoid using that many queries? 我可以避免使用那么多查询吗?

I'm also working with laravel framework, I don't know if it comes with any "tool" to accomplish what I want. 我也在使用laravel框架,我不知道它是否带有任何“工具”来完成我想要的东西。

Thanks in advance 提前致谢

What you are looking for is to use the UPDATE statement and the WHERE statement to seive out what you require, and this is how you do it. 您正在寻找的是使用UPDATE语句和WHERE语句来设置您需要的内容,这就是您的操作方法。 Parse the command through laravel and it will update accordingly. 通过laravel解析命令,它将相应更新。

UPDATE TableName Set Tickets=Tickets+1 WHERE USERNAME='JonDoe' AND Money > 200

使用Eloquent:

\App\User::where('username','JonDoe')->where('Money','>',200)->increment('Tickets');

I'm not expert with Laravel, but as many other frameworks, it should have an ORM system ( Object Relational Mapping : https://en.wikipedia.org/wiki/Object-relational_mapping ), this systems helps you to 'speak' to databases in an object oriented fashion ( with methods like getFirstByPrimaryKey( $primaryKey ) ). 我不是Laravel的专家,但是和其他许多框架一样,它应该有一个ORM系统(对象关系映射: https ://en.wikipedia.org/wiki/Object-relational_mapping),这个系统可以帮助你“说话”以面向对象的方式使用数据库(使用getFirstByPrimaryKey($ primaryKey)等方法)。

This said, I think that kind of systems are better when you already know how to do it manually. 这就是说,我认为当你已经知道如何手动完成时,那种系统会更好。

In the case you are proposing, you have to think first what you need, and then think what's the better approach to accomplish it. 在你提议的情况下,你必须首先考虑你需要什么,然后想想实现它的更好方法是什么。

What you need: 你需要什么:

Insert a ticket for one user if that user has more or equals some quantity. 如果该用户具有更多或等于某个数量,则为一个用户插入故障单。

Let me suppose, perhaps you're going to detry that quantity from money field after a successful ticket creation, right ? 让我想一想,也许你会在成功创建门票之后从金钱领域中取出这笔数量,对吧?

So I think we're selling a ticket, and the normal steps should be: 所以我认为我们正在卖票,正常的步骤应该是:

  • Check if user is logged. 检查用户是否已登录。 If it's logged, we probably have the user id in session or a similar system. 如果已记录,我们可能在会话或类似系统中具有用户ID。 It's much better to search in indexed numeric fields, if possible. 如果可能的话,在索引数字字段中搜索要好得多。

  • Once we have the user_id, we update the row if that user id has enough money for this action: 获得user_id后,如果该用户ID有足够的资金用于此操作,我们会更新该行:

//pseudo code
        $userId = 12;
        $cost = 200;
        $query = "update ticketstable set tickets=tickets+1, money=money-$cost 
    where id='$userId' and money >= $cost";
        $result = $db->query($query);

        if($result){
          //row with id = $userId has been updated
        }else{
          //There's not a row with $userId, or that row's money was less than $cost
        }

Take in account when dealing with money operations that you should make all related queries as a transaction ( a transaction in database argot means several sql sentences executed together, in a way that if some fails, all others are reverted, to avoid inconsistency ). 在处理货币操作时考虑到你应该将所有相关查询作为一个交易(数据库中的事务argot意味着一起执行几个sql语句,如果一些失败,所有其他的都被还原,以避免不一致)。

If you divide my proposal in two queries: 如果您在两个查询中划分我的提案:

1) check if user with id=x has money >= $cost; 1)检查id = x的用户是否有钱> = $ cost;

2) update money -= $cost; 2)更新资金 - = $ cost;

You can find in a situation where the user or other automated process takes some money from the same row between the steps 1 and 2, and then you end with negative money, and allowing an operation you shouldn't. 您可以在用户或其他自动化流程从步骤1和步骤2之间的同一行中获取一些资金的情况下找到,然后以负资金结束,并允许您不应该进行操作。

Laravel has the fluent query builder which you can use (more or less) like below: Laravel有一个流畅的查询构建器,您可以使用(或多或少)如下所示:

$affectedRows = DB::table('TableName')
    ->where("Username", "Jondoe")
    ->where("Money",">",200)
    ->increment("Tickets");

You can also use $affectedRows to check if there were any updates made. 您还可以使用$affectedRows来检查是否有任何更新。

Edit: 编辑:

If you have a user model (eg named User ) then you can use the same syntax but with Eloquent. 如果您有一个用户模型(例如,名为User ),那么您可以使用相同的语法,但使用Eloquent。

Example: 例:

User::where("Username", "Jondoe")
    ->where("Money",">",200)
    ->increment("Tickets");

Eloquent is Laravel's ORM (Object-Relational model) which provides a mapping between relational databases and PHP objects (ie the model part of the MVC framework). Eloquent是Laravel的ORM(对象关系模型),它提供了关系数据库和PHP对象(即MVC框架的模型部分)之间的映射。 It's not a query builder itself but it does use fluent in the background to build queries. 它不是一个查询构建器本身,但它确实使用流畅的后台来构建查询。

Reference https://laravel.com/docs/5.0/queries 参考https://laravel.com/docs/5.0/queries

Try This Command 试试这个命令

UPDATE TableName Set Tickets=Tickets+1 WHERE USERNAME='JonDoe' AND Money > 200

Hopefully This will solve your problem 希望这将解决您的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM