【问题标题】:"ambiguous column name" in SQLite INNER JOINSQLite INNER JOIN 中的“不明确的列名”
【发布时间】:2010-10-08 00:02:42
【问题描述】:

我在 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;

SQLite 不喜欢它:

SQL error: ambiguous column name: ItemId

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

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

【问题讨论】:

    标签: sql sqlite join


    【解决方案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));
    }
    

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

    【讨论】:

    • 我最终做了这样的事情。我从不允许用户直接编写 SQL,但 WHERE 子句是使用表达式模板构建的。在需要的地方限定列名就足够了。
    【解决方案2】:

    只需将您的列别名更改为类似但唯一的名称(例如 ITEM_ID)。

    【讨论】:

      【解决方案3】:

      我会这样写这个查询:

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

      我正在使用 USING (ItemId) 语法,这只是个人喜好问题。相当于ON (i.ItemID = s.ItemID)

      但我通过在 WHERE 子句中限定 i.ItemID 解决了歧义。你会认为这是不必要的,因为i.ItemID = s.ItemID。它们在交换性上是相等的,所以没有语义上的歧义。但显然 SQLite 不够聪明,无法知道这一点。

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

      【讨论】:

        猜你喜欢
        • 2019-04-05
        • 2015-08-15
        • 2014-05-03
        • 1970-01-01
        • 1970-01-01
        • 2014-12-23
        • 2020-09-19
        • 2015-11-02
        • 1970-01-01
        相关资源
        最近更新 更多