2013-08-28 242 views
3

我有一個postgresql數據庫,我試圖做的是從儘可能少的查詢中刪除表中的一堆行。所以循環不是一個好的選擇。我正在使用NPGSQL作爲postgres驅動程序。使用WHERE IN子句刪除PostgreSQL中的多行使用WHERE IN子句

我有下面的代碼,但它不工作。試圖執行的最後一個查詢時錯誤

 string[] namesToDelete = PromosReplies. 
         PromosRepliesLoaded.GroupBy(pr => pr.Name). 
         Select(r=>r.Key).ToArray(); 
     long[] repliesIdsToDelete = context.PromosReplies. 
            Where(pr => namesToDelete.Contains(pr.Name)). 
            Select(r => r.Idx).ToArray(); 
     if (repliesIdsToDelete.Length > 0) 
     { 
      foreach (var name in namesToDelete) 
      { 
      context.Database.ExecuteSqlCommand("DELETE FROM messages WHERE name = {0}", name); 
      } 
      string idToDelete = String.Join(",", repliesIdsToDelete); 
      int result = context.Database.ExecuteSqlCommand(
       "DELETE FROM message_translations WHERE idx IN ({0})", 
       repliesIdsToDelete); 

我得到一個「錯誤:22P02:無效的輸入語法整數」。有沒有辦法解決這個問題?如果是的話,我可以使用第一個刪除語句來做類似的事情嗎?

回答

4

更新 我不能與EF工作,但這裏的使用數組作爲參數與Npgsql的方式:

var cmd = NpgsqlCommand(); 
cmd.CommandText = "select * from test where id = any(@list)"; 
cmd.Connection = "**************************"; 
cmd.Parameters.Add("list", NpgsqlDbType.Array | NpgsqlDbType.Integer); 
cmd.Connection.Open(); 
var r = cmd.ExecuteReader(); 

所以我在EF想這會是這樣的:

var par = new NpgsqlParameter("list", NpgsqlDbType.Array | NpgsqlDbType.Text); 
var par.Value = namesToDelete; 
int result1 = context.Database.ExecuteSqlCommand(
    "DELETE FROM messages WHERE name = any(@list)", 
    par 
); 

我不喜歡這個,因爲它可能會導致SQL注入:

int result1 = context.Database.ExecuteSqlCommand(
    String.Format(
     "DELETE FROM messages WHERE name in ({0})", 
     String.Join(",", namesToDelete.Select(x => "'" + x + "'")) 
    ) 
); 

int result2 = context.Database.ExecuteSqlCommand(
    String.Format(
     "DELETE FROM message_translations WHERE idx in ({0})", 
     String.Join(",", repliesIdsToDelete) 
    ) 
); 

我不是的EntityFramework的專家,但我認爲當你使用context.Database.ExecuteSqlCommand(command, str),STR作爲參數,所以你的命令變得DELETE FROM message_translations WHERE idx in ('1, 2, 3, 4')(注意單引號,'1, 2, 3, 4'實際上是在服務器端的字符串)。

如果您的數據庫是SQL服務器,可以使用表值參數,可以將數組作爲參數傳遞到PostgreSQL中,稍後再嘗試。

+0

同樣的錯誤。這個=號是我的一個錯字。 – idipous

+0

@idipous你是否嘗試過傳遞字符串(不是列表)?改變了答案,檢查它 –

+0

@idipous可以用'string.format'嘗試嗎? –