根据表数据有条件地执行 SQL 查询/语句
Posted
技术标签:
【中文标题】根据表数据有条件地执行 SQL 查询/语句【英文标题】:Execute a SQL query/statement conditionally based on table data 【发布时间】:2016-11-02 08:14:50 【问题描述】:首先,看看这张表,基本上我需要更新(+1)一张票,其中用户名等于 Jondoe 并且金钱大于 200。
现在,我知道我可以执行 3 个查询,首先检查实际用户是否有 Jondoe 作为用户名,然后检查他是否有足够的钱,如果这些结果是真的,最后更新(+1)一张票。
我正在学习 SQL,并且正在使用 mssql 数据库,那么进行这种条件查询/更新的正确方法是什么?我可以避免使用那么多查询吗?
我也在使用 laravel 框架,我不知道它是否带有任何“工具”来完成我想要的。
提前致谢
【问题讨论】:
您可能有一个触发器来停止插入无效值。 如果你有更新记录 where username = 'Jondoe' 你想使用更新查询而不是插入。 是的,我的错。我刚刚更新了我的问题。谢谢@NikhilVaghla 【参考方案1】:您正在寻找的是使用 UPDATE 语句和 WHERE 语句来筛选出您需要的内容,这就是您的操作方式。通过 laravel 解析命令,它会相应地更新。
UPDATE TableName Set Tickets=Tickets+1 WHERE USERNAME='JonDoe' AND Money > 200
【讨论】:
SET Tickets=Tickets+1
可能更类似于 OP 的要求。
我是根据他之前的问题提出的,没有关注他更新的问题。
我现在正在测试它,考虑到我正在使用 php,如果用户名或资金不符合条件,有什么方法可以“捕获”错误?
可能对 laravel 上下文不太熟悉,但对于通用 PHP,try and catch 就足够了。给我一点时间来解决这个问题。
@Frondor,这取决于数据库,但我认为在这种情况下你不能。如果满足某些条件,您要求数据库更新一行的一个字段,如果在需要的地方没有更新,您知道某些条件没有满足,但您不能说是哪个条件。但在这种情况下,当您要求钱 >= 数量时,正如 apokryfos 指出的那样,您只有两个选择:用户不存在或钱不够。【参考方案2】:
使用 Eloquent:
\App\User::where('username','JonDoe')->where('Money','>',200)->increment('Tickets');
【讨论】:
我认为 Eloquent 是我这次最好的选择,一定要检查一下。谢谢! 如果你已经有一个用户模型,那么 eloquent 就比 fluent 好(它实际上是建立在它之上的)。【参考方案3】:我不是 Laravel 方面的专家,但与许多其他框架一样,它应该有一个 ORM 系统(对象关系映射:https://en.wikipedia.org/wiki/Object-relational_mapping),该系统可以帮助您以面向对象的方式与数据库“对话”(使用getFirstByPrimaryKey( $primaryKey ) ) 等方法。
也就是说,我认为当您已经知道如何手动操作时,这种系统会更好。
如果你提出建议,你必须首先考虑你需要什么,然后考虑什么是更好的方法来完成它。
你需要什么:
如果该用户拥有更多或等于某个数量,则为该用户插入一张票。
让我假设,在成功创建票证后,您可能会从货币字段中删除该数量,对吧?
所以我认为我们是在卖票,正常的步骤应该是:
检查用户是否已登录。如果它被记录,我们可能在会话或类似系统中有用户 ID。如果可能,最好在索引数字字段中进行搜索。
一旦我们有了 user_id,如果该用户 id 有足够的钱来执行此操作,我们就会更新该行:
//伪代码 $userId = 12; $成本= 200; $query = "更新tickettable设置tickets=tickets+1,money=money-$cost 其中 id='$userId' 和金钱 >= $cost"; $result = $db->query($query); 如果($结果) // id = $userId 的行已更新 别的 //没有$userId的行,或者该行的钱小于$cost在处理货币操作时要考虑到你应该将所有相关的查询作为一个事务进行(数据库中的一个事务是指几个sql语句一起执行,如果一些失败,所有其他的都被还原,以避免不一致)。
如果您将我的提案分为两个查询:
1) 检查 id=x 的用户是否有钱 >= $cost;
2) 更新资金 -= $cost;
您可能会发现用户或其他自动化流程在步骤 1 和 2 之间从同一行中取了一些钱,然后您以负数结束,并允许您不应该进行的操作。
【讨论】:
【参考方案4】:Laravel 有流畅的查询构建器,你可以使用(或多或少)如下:
$affectedRows = DB::table('TableName')
->where("Username", "Jondoe")
->where("Money",">",200)
->increment("Tickets");
您也可以使用$affectedRows
检查是否有任何更新。
编辑:
如果您有一个用户模型(例如,名为 User
),那么您可以使用相同的语法,但使用 Eloquent。
例子:
User::where("Username", "Jondoe")
->where("Money",">",200)
->increment("Tickets");
Eloquent 是 Laravel 的 ORM(对象关系模型),它提供了关系数据库和 PHP 对象(即 MVC 框架的模型部分)之间的映射。它本身不是查询构建器,但它确实在后台使用流利的方式来构建查询。
参考https://laravel.com/docs/5.0/queries
【讨论】:
谢谢!我意识到了这一点。可悲的是,我认为这意味着 2 个查询 + 最后的增量......与UPDATE TableName Set Tickets=Tickets+1 WHERE USERNAME='JonDoe' AND Money > 200
相比,这不是一种“矫枉过正”吗?
Fluent 是一个查询构建器。它基于函数链构建单个查询。 where
,whereIn
等函数只是将段添加到查询中,increment,update,insert,get,first
等函数构建并执行查询。
这是很酷的信息@apokryfos,但是如果找不到用户,或者他/她没有足够的钱怎么办?我怎样才能“捕捉”这些错误?我的意思是,返回正确的错误
从技术上讲,因为条件不匹配而不更新任何用户并不是错误。但是,在我更新的回复中,有 $affectedRows
变量可以告诉您更新了多少用户。如果用户名是唯一的,则该值将是 0
(意味着用户不存在或没有足够的钱,如果您想知道哪个是您需要运行另一个查询的问题)或1
(表示一切正常)。
知道了!我希望我可以选择这个,以及关于 Eloquent 作为最佳答案的那个,但遗憾的是我不能。【参考方案5】:
试试这个命令
UPDATE TableName Set Tickets=Tickets+1 WHERE USERNAME='JonDoe' AND Money > 200
希望这能解决你的问题
【讨论】:
以上是关于根据表数据有条件地执行 SQL 查询/语句的主要内容,如果未能解决你的问题,请参考以下文章