sql >> Databáze >  >> RDS >> Mysql

Dynamický dotaz s proměnným počtem IN (p1, p2, p3) argumentů

Z komentářů:

depToDelete a otherToDelete jsou seznam (řetězců), který přechází z volání funkce. Tyto obsahují 1 nebo více vodítek, které chci smazat

Z tohoto důvodu jej váš kód neformátuje správně pro SQL. Pro seznam 2 Guid Strings po připojení získáte toto:

"af489fbf-982a-49de-b73e-2ac3f3192225, 0feab28d-4f96-456a-9f36-0a0376627128"

Potom strOtherToDelete = strOtherToDelete.Replace(Chr(34), Chr(39)).Substring(1, 77) zřejmě se chce pokusit odstranit nabídku a nahradit ji zaškrtnutím. Problém je v tom, že samotný řetězec neobsahuje nabídku. Vidíte to v IDE, protože to je způsob, jak vám VS říct, že jde o řetězec.

SubString krokem je oříznutí platných znaků Guid z výsledku (a magického čísla 77 umožňuje jeho zhroucení, když jich není právě správný počet):

Před:"9b842f14-7932-4e3d-8483-07790ccc674c, ...
&After:"b842f14-7932-4e3d-8483-07790ccc674c,...

To nebude fungovat, protože obsah není jeden příliš dlouhý průvodce. Každý prvek v List je třeba zaškrtnout. Chcete-li zaškrtnout každý prvek v seznamu, musíte vytvořit smyčku a vytvořit řetězec nebo použít linq.

To ale také nebude fungovat. MySQL prostě nemá rád výsledný řetězec od poskytovatele NET tímto způsobem a nedělá pole parametrů, takže...

Pojďme tedy vytvořit modul parametrů:

Nemá smysl pracovat se 2 sadami vodítek, takže je spojte (jedná se o skutečný List(of String) obsahující guids, ne něco jiného, ​​ne json):

Dim depVals = depToDelete.Concat(otherToDelete).ToList

' your sql here
Dim sql = "DELETE FROM DEMO WHERE GuidString IN (@magic)"
' param storage
Dim gvalues As New List(Of String)

' create a list of "@g" param placeholders
Dim ndx As Int32 = 0
For ndx = 0 To depVals.Count - 1
    ' adds a "@gN" value to the List
    gvalues.Add(String.Format("@g{0}", (ndx + 1).ToString))
Next

' insert them into the SQL string
sql = sql.Replace("@magic", String.Join(", ", gvalues))
' '@magic' replaced with "@g1, @g2, @g3..." 

Using cmd As New MySqlCommand(sql, dbcon)
    dbcon.Open()

    ' create an equal number of Paramerters, set the value of each
    For n As Int32 = 0 To gvalues.Count - 1
       ' add parm "@gN", assign value from 'depVals`
       cmd.Parameters.Add(gvalues(n), MySqlDbType.String).Value = depVals(n)
    Next

   ' debug:
   Dim fullSQL = GetFullCommandSQL(cmd)
   Console.WriteLine(fullSQL)

   Dim rows = cmd.ExecuteNonQuery()
End Using

Výstup ladění je syntakticky správný:

...a 3 řádky s těmito GUID budou smazány!

Také:

  • Bloky Empty Catch jsou špatné, protože skrývají problémy před jedinou osobou, která je může opravit (vy).
  • Měli byste použít možnost Option Strict, abyste zabránili VB hádat, co máte na mysli pod určitými věcmi.



  1. Jak funguje REGEXP_INSTR() v MariaDB

  2. CakePHP 3 - Analyzujte datum pomocí LocalStringFormat pro opravu formátu SQL a správné ověření

  3. 3 způsoby formátování čísla na 2 desetinná místa v Oracle

  4. Ekvivalent Postgresql GROUP_CONCAT?