SQLite INNER JOIN中的"模糊列名"

gga*_*ett 5 sql sqlite join

我在SQLite DB,INVITEM和SHOPITEM中有两个表.他们的共享属性是ItemId,我想执行INNER JOIN.这是查询:

    SELECT  INVITEM.CharId AS CharId, 
            INVITEM.ItemId AS ItemId 
      FROM  (INVITEM as INVITEM 
INNER JOIN  SHOPITEM AS SHOPITEM 
        ON  SHOPITEM.ItemId = INVITEM.ItemId)
     WHERE  ItemId = 3;
Run Code Online (Sandbox Code Playgroud)

SQLite不喜欢它:

SQL error: ambiguous column name: ItemId
Run Code Online (Sandbox Code Playgroud)

如果我写的话WHERE INVITEM.ItemId = 3,错误就会消失,但由于WHERE条件或多或少是用户指定的,所以我宁愿让它工作而不必指定表.NATURAL JOIN似乎解决了这个问题,但我不确定解决方案是否足够通用(即我可以在这种情况下使用,但我不确定我是否可以在每种情况下使用)

任何可以解决问题的替代SQL语法?

Bil*_*win 10

我会这样写这个查询:

SELECT i.CharId AS CharId, i.ItemId AS ItemId 
FROM INVITEM as i INNER JOIN SHOPITEM AS s USING (ItemId)
WHERE i.ItemId = 3;
Run Code Online (Sandbox Code Playgroud)

我正在使用的USING (ItemId)语法只是一种品味问题.它相当于ON (i.ItemID = s.ItemID).

但是我通过条款中的资格i.ItemID来解决了这种含糊不清的问题WHERE.你会认为这是不必要的,因为i.ItemID = s.ItemID.它们都具有交换性,因此没有语义模糊性.但显然SQLite并不够聪明,不知道这一点.

我不喜欢用NATURAL JOIN.它相当于两个表中存在的具有相同名称的列的等连接.我不喜欢使用它,因为我不希望它比较我不想要它的列,只是因为它们具有相同的名称.


geo*_*tnz 1

我会避免允许用户直接编写 SQL 子句。这就是SQL注入漏洞的根源。

如果您需要灵活的查询,请尝试解析用户的输入并添加适当的 where 子句。

下面是一些 C# 代码来展示总体思路

// from user input
string user_column = "ItemID";
string user_value = "3";

string sql = "SELECT INVITEM.CharId AS CharId, INVITEM.ItemId AS ItemId FROM (INVITEM as INVITEM INNER JOIN SHOPITEM AS SHOPITEM ON SHOPITEM.ItemId = INVITEM.ItemId) ";

if (user_column == "ItemID")
{
    // using Int32.Parse here to prevent rubbish like "0 OR 1=1; --" being entered.
    sql += string.Format("WHERE INVITEM.ItemID={0}",Int32.Parse(user_value));
}
Run Code Online (Sandbox Code Playgroud)

显然,如果您要处理多个子句,则必须在后续子句中用 AND 替换 WHERE。