Member 11856456 Ответов: 1

Дублирование SQL-оператора в обычную форму


Я пытаюсь использовать свои контрольные списки для заполнения полей T. или S. тем, что выбрано. Это моя первая попытка использовать формат добавления. Мне нужна помощь, чтобы разобраться в этом. Я поместил исходный SQL-оператор ниже.

Private Sub sompare_other_tables()

       Dim sqlcon As New SqlConnection("sqlstatement")

       Dim cb As New System.Text.StringBuilder("MERGE INTO")
       Dim tableName As String = ListBox1.SelectedItems(Convert.ToString(tableName))
       Dim tablename2 As String = ListBox2.SelectedItems(Convert.ToString(tablename2))
       cb.AppendFormat(" [{0}] ", tableName.Replace("]", "]]"))
       cb.Append("as T")
       cb.AppendFormat(" using [{0}] ", tablename2.Replace("]", "]]"))
       cb.Append("As S ")
       '  cb.AppendFormat(", [{0}] nvarchar(max) NULL", tableName.Replace("]", "]]"))
       cb.AppendFormat("on T.", tableName.Replace("]", "]]"))
       cb.Append(Convert.ToString(" = "))
       cb.Append("[{0}] S.", tablename2.Replace("]", "]]"))

       For Each item In CheckedListBox1.CheckedItems
           Dim columnName As String = Convert.ToString(item)
           cb.AppendFormat("on T." + columnName.Replace("]", "]]"))
           cb.Append(" = ")
           cb.Append("S." + columnName.Replace("]", "]]"))

       Next

       Dim sql As String = cb.ToString()

       sqlcon.Open()
       Dim cmd As SqlClient.SqlCommand
       cmd = New SqlClient.SqlCommand(sql, sqlcon)

       MessageBox.Show(cmd.CommandText)

       cmd.ExecuteNonQuery()
       sqlcon.Close()


Это исходный оператор SQL:

Merge into table1 as T using [table] as S on T.[Last Name] = S.[Last Name] and T.[First Name] = S.[First Name] 
When Matched then Update Set T.[Birth] = S.[Birth];

DELETE T1 FROM [table] T1 JOIN [table1] T2 ON T1.[Last Name]  = T2.[Last Name] AND T1.[First Name]  = T2.[First name];


Что я уже пробовал:

Я не очень-то старался, так как мало что знаю о добавлениях. если есть лучший способ написать заявление, я бы с удовольствием его выслушал.

1 Ответов

Рейтинг:
4

CHill60

Если вы посмотрите на линию

cb.AppendFormat("on T.", tableName.Replace("]", "]]"))
Вы не поместили заполнитель в строку для значения, которое вы используете. Я ожидал бы чего-то вроде
cb.AppendFormat("on T.{0}", tableName.Replace("]", "]]"))
Аналогично, вы использовали конкатенацию строк в строке
cb.AppendFormat("on T." + columnName.Replace("]", "]]"))
так что не было никакого смысла в использовании AppendFormat, вы могли бы просто использовать Append Избегайте конкатенации строк и делайте это вместо этого:
cb.AppendFormat("on T.{0}", columnName.Replace("]", "]]"))
Теперь рассмотрим линию
cb.Append(Convert.ToString(" = "))
Нет никакой необходимости в Convert.ToString()... " = " это уже строка

При использовании AppendFormat вы можете включить несколько переменных в список форматов, чтобы сделать код немного более аккуратным. Например, вы можете заменить
        cb.AppendFormat(" [{0}] ", tableName.Replace("]", "]]"))
cb.Append("as T")
cb.AppendFormat(" using [{0}] ", tablename2.Replace("]", "]]"))
cb.Append("As S ")
с
cb.AppendFormat(" [{0}] as T using [{1}] as S", tableName.Replace("]", "]]"), tablename2.Replace("]", "]]"))
Без пользы от каких-либо данных в ваших списках немного трудно комментировать все остальное. Например непонятно почему вы заменяете ] с ]] и т.д.

Поскольку предложение ON повторяется как в update, так и в delete sql, я бы создал его как отдельный StringBuilder так что вы можете использовать его повторно.

Это код, который я придумал, но вам придется проверить вывод, чтобы убедиться, что он правильный после подключения ваших данных из элементов управления списком:
Dim cb2 As New StringBuilder("MERGE INTO ")
  cb2.AppendFormat("{0} as T using {1} as S", tableName, tablename2)

  Dim sbOn As New StringBuilder(" ON ")
  Dim andRequired As Boolean = False
  For Each item In CheckedListBox1.CheckedItems
      If andRequired Then
          sbOn.Append(" AND ")
      End If
      Dim columnName As String = item.ToString()
      sbOn.AppendFormat("on T.[{0}] = S.[{1}]", columnName, columnName)
      andRequired = True
  Next
  cb2.Append(sbOn.ToString())
  cb2.Append("When Matched then Update Set T.[Birth] = S.[Birth];")

  cb2.AppendFormat("DELETE T1 FROM [{0}] T1 JOIN [{1}] T2", tablename2, tableName)
  cb2.Append(sbOn.ToString())

  Debug.Print(cb2.ToString())
Обратите внимание на трюк, который я использовал, чтобы убедиться, что я не получу лишнего AND в ON пункт


Member 11856456

Я не уверен, каков будет результат. Когда я запускаю код, я получаю эту ошибку:

Дополнительная информация: попытка прикрепить базу данных с автоматическим именем для файла c:\users\jj\documents\visual studio 2015\Projects\WindowsApplication3\WindowsApplication3\Database1. mdf не удалось. База данных с таким же именем существует, или указанный файл не может быть открыт,или он находится на общем ресурсе UNC.

CHill60

Этого не происходит в коде, который я предоставил - возможно, именно тогда вы подключаетесь к базе данных? Проверьте правильность строки подключения