4

我在這個可愛的星球上做了很多參數化的查詢,並沒有發生這樣的錯誤... WTFudge?!?!與SqlCe參數的錯誤

錯誤:

There was an error parsing the query. [ 
Token line number = 1, 
Token line offset = 20, 
Token in error = @table ] 

顯然,編譯器不喜歡我的SQL語句......但我看不出有什麼問題???

這是我的代碼。

using (SqlCeConnection con = new SqlCeConnection(_connection)) 
{ 
    string sqlString = "SELECT @colID FROM @table WHERE @keyCol = @key"; 

    SqlCeCommand cmd = new SqlCeCommand(sqlString, con); 
    cmd.Parameters.Add(new SqlCeParameter("@table", tableName)); 
    cmd.Parameters.Add(new SqlCeParameter("@colID", columnIdName)); 
    cmd.Parameters.Add(new SqlCeParameter("@keyCol", keyColumnName)); 
    cmd.Parameters.Add(new SqlCeParameter("@key", key)); 

    try 
    { 
     con.Open(); 
     return cmd.ExecuteScalar(); 
    } 
    catch (Exception ex) 
    { 
     Console.Write(ex.Message); 
     throw new System.InvalidOperationException("Invalid Read. Are You Sure The Record Exists", ex); 
    } 
    finally 
    { 
     if (con.State == ConnectionState.Open) 
      con.Close(); 
     cmd.Dispose(); 
     GC.Collect(); 
    } 
} 

正如你可以看到它的一個非常簡單的SQL語句。我雖然「@table」可能已被愚蠢地保留或某事...所以我嘗試了@tableName,@var,@everything !!!不知道問題是什麼。

在調試期間,我檢查了SqlCeParameterCollection中實際上有一個@table參數並且它在那裏。當天清除!

Image: Debug Information

+1

語法和功能有限。您不能使用表(或視圖)名稱的參數。 –

+0

這將工作在SqlExpress? –

+0

不,坦率地說,我不知道任何接受表名參數的SQL引擎。您始終可以在C#中使用字符串創建動態查詢。 –

回答

4

既然你在C#(而不是存儲的特效)

string sqlString = "SELECT " + columnIdName + 
" FROM " +tableName "WHERE " + keyColumnName + "= @key"; 

你會想驗證columnIdName,表名,keyColumnName都離不開值的列表(或最少限制長度爲50個字符),否則此過程針對不安全和SQL注入攻擊進行了優化。

+0

SQL注入在這裏? – Coops

+0

@CodeBlend你讀過答案了嗎?表名不能是參數。開發人員需要制定一些策略,將惡意用戶內容保留在字符串之外,例如使用常量列表,在構建字符串之前查看錶格/列名稱,不允許使用非字母字符串等我不能不知道更多關於他的應用程序。 – MatthewMartin

+0

@MathewMarting足夠公平的你提出一個有效的觀點,如果我已經詳細閱讀了我可能不會評論,那是我的不好。感謝您的詳細回覆。 – Coops

1

這也影響了我在SqlCe上。但是在Sql Server和SqlExpress中,你可以使用一個paarameter作爲表名。