SQL Выбор между 3 таблицами — Не удается преобразовать в ошибку int

#sql #vb.net #tsql

#sql #vb.net #tsql

Вопрос:

у меня проблема с вложенным кодом SQL. При выборке переменной INT на основе Nvarchar я не понимаю, почему это вернет ошибку, поэтому могла бы воспользоваться вашей помощью.

У меня есть структура таблицы, изложенная следующим образом-

  • SONGS_DB SONG_ID, SONG_NAME

  • SONG_PLAYLIST SONG_PLAYLIST_ID, SONG_ID, PLAYLIST_ID списка ВОСПРОИЗВЕДЕНИЯ

  • Список воспроизведения PLAYLIST_ID, PLAYLIST_NAME

Я пытаюсь отобразить все песни из одного списка воспроизведения в datagridviewer с помощью следующего кода-

 Dim con As New SqlConnection With {.ConnectionString = "Data Source=(LocalDB)MSSQLLocalDB;AttachDbFilename=C:UserscooljOneDriveDocumentsLoopLoopSongs_SQL.mdf;Integrated Security=True"}
    Dim cmd As New SqlCommand("SELECT SONG_ID, SONG_NAME FROM SONGS_DB WHERE SONG_ID IN (SELECT SONG_ID FROM SONG_PLAYLIST WHERE PLAYLIST_ID IN (SELECT PLAYLIST_ID FROM Playlist WHERE PLAYLIST_NAME = (@NAME)))", con)
    cmd.Parameters.AddWithValue("@NAME", ComboBox1.SelectedIndex)

    Dim Ada As New SqlDataAdapter(cmd)
    Dim Table As New DataTable()
    Ada.Fill(Table)

    DataGridView1.DataSource = Table
End Sub
  

Однако он возвращает следующую ошибку-

«Ошибка преобразования при преобразовании значения nvarchar ‘Party Hits ‘ в тип данных int.’

Party hits — это название первого списка воспроизведения, меня это смущает, потому что я не вижу причин для преобразования party hits в int. Есть идеи?

Комментарии:

1. попробуйте использовать selecteditem вместо selectedindex, вы сравниваете int с текстовым полем в SQL

2. Пожалуйста, покажите, как вы заполняете коллекцию элементов ComboBox1. Используете ли вы источник данных или элементы. Добавить?

3. Похоже, что PLAYLIST_NAME содержит «name», где as .SelectedIndex должно быть int. Чего мне не хватает?

Ответ №1:

Эта строка

  cmd.Parameters.AddWithValue("@NAME", ComboBox1.SelectedIndex)
  

возвращает индекс текущего выбранного элемента в выпадающем списке. И это число, а не название списка воспроизведения.

Если вы хотите получить название этого списка воспроизведения, вы могли бы использовать

  cmd.Parameters.AddWithValue("@NAME", ComboBox1.SelectedItem.ToString())
  

но точные свойства для использования зависят от того, как вы инициализируете содержимое ComboBox.
Если вы добавляете список воспроизведения по одному имени за раз, вы могли бы использовать описанный выше метод, но если вы заполняете источник данных, тогда вам нужно рассмотреть возможность извлечения информации из коллекции объектов, используемой для заполнения источника данных

Например, в случае заполнения комбо DataTable, как в этом коде

 Dim con As New SqlConnection With {.ConnectionString = "....."}
Dim cmd As New SqlCommand("SELECT * FROM Playlist", con)
Dim Ada As New SqlDataAdapter(cmd)
Dim Table As New DataTable()
Ada.Fill(Table)

' Here the collection of items is a collection of DataRowView
' and we tell the ComboBox what to display and what to use for the SelectedValue property
ComboBox1.DisplayMember = "PLAYLIST_NAME"
ComboBox1.ValueMember = "PlayList_ID"
ComboBox1.DataSource = Table
  

Затем вы могли бы получить свое имя с

 Dim drv As DataRowView = CType(ComboBox1.SelectedItem, DataRowView)
Dim name as String = drv("Name").ToString()
  

В качестве последнего совета я предлагаю вам изменить ваш запрос и использовать более «простой» и стандартный оператор join

 SELECT S.SONG_ID, S.SONG_NAME 
FROM SONGS_DB S 
   LEFT JOIN SONG_PLAYLIST SP ON S.SONG_ID = SP.SONG_ID
   LEFT JOIN Playlist P ON SP.PlayList_ID = p.PlayList_ID
WHERE p.PLAYLIST_NAME = @NAME",
  

Комментарии:

1. Привет, Стив, спасибо за ответ, ваш комментарий вверху действительно устранил ошибку, однако datagridviewer все еще не заполняется. Спасибо за пример, но помните, что я хочу заполнить сетку названиями песен и идентификаторами, а не списками воспроизведения, которые находятся в отдельной таблице

2. Что ж, вам нужно отладить свой код и проверить, какие значения содержатся в переменных. Например, проверьте, что такое Table.Rows. Посчитайте значение после заполнения таблицы.

3. Мой второй фрагмент кода — это пример того, как заполнить ComboBox1, а не DataGridView, именами списков воспроизведения без использования цикла для вставки имен одно за другим. Это было просто для того, чтобы объяснить, что разные методы загрузки требуют разных методов извлечения. Если вы вставляете названия плейлистов одно за другим, то SelectedItem. toString разрешает имя