无法使用 ADO.NET 连接架构从 SQL 服务器读取数据
Can't read data from SQL Server using ADO.NET connected architecture
当我尝试使用 SqlDataReader
从本地数据库读取数据并将数据插入 ListBox
时出现问题。我得不到任何结果,即使我应该。问题是当我在 SSMS 中 运行 ingilizceSorgusu
时,它工作正常,我可以将数据检索到结果 table 中。我认为我在 SqlDataReader
.
中遗漏了一些东西
这是我的代码:
public partial class Arama : Form
{
#region Nesneler
SqlCommand Sorgu;
SqlConnection Baglanti;
SqlDataReader Okuyucu;
IEnumerator Numarala;
string baglantiCumlesi = @"Server = ABRA\VERITABANIM;Initial Catalog = Sozluk; Integrated Security = True";
string ingilizceSorgusu = "SELECT [KA].[Anlam] " +
"FROM [KelimeAnlam] [KA] " +
"LEFT OUTER JOIN [IngKelimeler] [IK] ON [KA].[KelimeID] = [IK].[ID] " +
"WHERE [IK].[Kelime] LIKE '@deger%'";
string turkceSorgusu = "SELECT [IK].[Kelime] " +
"FROM [IngKelimeler] [IK] " +
"LEFT OUTER JOIN [KelimeAnlam] [KA] ON [KA].[KelimeID] = [IK].[ID] " +
"WHERE [KA].[Anlam] LIKE '@deger%'";
#endregion
#region Metotlar
public Arama()
{
InitializeComponent();
ingilizceSecim.Select();
Baglanti = new SqlConnection(baglantiCumlesi);
Duzenle();
}
private void Duzenle()
{
kelimeGiris.Select();
kelimeGiris.SelectionStart = 0;
sonucListe.Items.Clear();
}
private void Cikis_Click(object sender, EventArgs e)
{
this.Close();
}
#endregion
#region Giriş alanı
private void KayitIsle(object sender, EventArgs e)
{
string girdi;
#region İngilizce seçim
if (ingilizceSecim.Checked)
{
#region Sorgu alanı
#region Girdi kontrol
if (!kelimeGiris.Text.Equals(String.Empty))
girdi = kelimeGiris.Text.ToLower();
else
{
MessageBox.
Show("Lütfen İngilizce kelime alanını boş bırakmayınız.",
"Boş alan",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
Duzenle();
return;
}
#endregion
#region Bağlantı
Baglanti.Open();
#region Sorgu
using (Sorgu = new SqlCommand(ingilizceSorgusu, Baglanti))
{
Sorgu.Parameters.AddWithValue("@deger", girdi);
Sorgu.CommandType = CommandType.Text;
Okuyucu = Sorgu.ExecuteReader();
// Can't retrieve data into ListBox here
while (Okuyucu.Read())
sonucListe.Items.Add(Okuyucu["Anlam"].ToString());
Okuyucu.Close();
}
#endregion
Baglanti.Close();
#endregion
#endregion
return;
}
#endregion
#region Türkçe seçim
if (turkceSecim.Checked)
{
#region Sorgu alanı
if (!kelimeGiris.Text.Equals(String.Empty))
girdi = kelimeGiris.Text.ToLower();
else
{
MessageBox.Show("Lütfen Türkçe kelime alanını boş bırakmayınız.",
"Boş alan",
MessageBoxButtons.OK,
MessageBoxIcon.Error,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.ServiceNotification);
Duzenle();
return;
}
#region Bağlantı
using (Baglanti = new SqlConnection(baglantiCumlesi))
{
Baglanti.Open();
#region Sorgu
using (Sorgu = new SqlCommand(turkceSorgusu, Baglanti))
{
Sorgu.Parameters.AddWithValue("@deger", girdi);
#region Sonuç aktarma
using (Okuyucu = Sorgu.ExecuteReader())
{
}
#endregion
}
#endregion
Baglanti.Close();
}
#endregion
#endregion
return;
}
#endregion
}
#endregion
#region Dil tercih değişim
private void ingilizceSecim_CheckedChanged(object sender, EventArgs e)
{
kelimeBaslik.Text = "İngilizce";
anlamBaslik.Text = "Türkçe";
}
private void turkceSecim_CheckedChanged(object sender, EventArgs e)
{
kelimeBaslik.Text = "Türkçe";
anlamBaslik.Text = "İngilizce";
}
#endregion
}
}
这与ADO.NET无关。如果在 SSMS 中执行,该查询也不会 return 任何结果。这是因为 LIKE '@deger%'
搜索以字符 @deger
开头的字符串。
查询参数类似于 函数 参数 - 它们不会注入到查询字符串中,而是作为 ... 值传递给已编译的查询。当客户端执行带参数的查询时,这些参数将发送到 外部 查询。这就是参数化查询不易受到 SQL 注入攻击的原因——值永远不会成为查询的一部分。 (除非开发人员特意重新引入该风险)。
在 SSMS 或存储过程中,正确的查询如下所示:
define @deger varchar(20)='whatever%'
SELECT [KA].[Anlam]
FROM [KelimeAnlam] [KA]
LEFT OUTER JOIN [IngKelimeler] [IK] ON [KA].[KelimeID] = [IK].[ID]
WHERE [IK].[Kelime] LIKE @deger
或
define @deger varchar(20)='whatever'
SELECT [KA].[Anlam]
FROM [KelimeAnlam] [KA]
LEFT OUTER JOIN [IngKelimeler] [IK] ON [KA].[KelimeID] = [IK].[ID]
WHERE [IK].[Kelime] LIKE @deger + '%'
查询字符串也必须使用其中一种形式,例如:
var ingilizceSorgusu = "SELECT [KA].[Anlam] " +
"FROM [KelimeAnlam] [KA] " +
"LEFT OUTER JOIN [IngKelimeler] [IK] ON [KA].[KelimeID] = [IK].[ID] " +
"WHERE [IK].[Kelime] LIKE @deger + '%'";
当我尝试使用 SqlDataReader
从本地数据库读取数据并将数据插入 ListBox
时出现问题。我得不到任何结果,即使我应该。问题是当我在 SSMS 中 运行 ingilizceSorgusu
时,它工作正常,我可以将数据检索到结果 table 中。我认为我在 SqlDataReader
.
这是我的代码:
public partial class Arama : Form
{
#region Nesneler
SqlCommand Sorgu;
SqlConnection Baglanti;
SqlDataReader Okuyucu;
IEnumerator Numarala;
string baglantiCumlesi = @"Server = ABRA\VERITABANIM;Initial Catalog = Sozluk; Integrated Security = True";
string ingilizceSorgusu = "SELECT [KA].[Anlam] " +
"FROM [KelimeAnlam] [KA] " +
"LEFT OUTER JOIN [IngKelimeler] [IK] ON [KA].[KelimeID] = [IK].[ID] " +
"WHERE [IK].[Kelime] LIKE '@deger%'";
string turkceSorgusu = "SELECT [IK].[Kelime] " +
"FROM [IngKelimeler] [IK] " +
"LEFT OUTER JOIN [KelimeAnlam] [KA] ON [KA].[KelimeID] = [IK].[ID] " +
"WHERE [KA].[Anlam] LIKE '@deger%'";
#endregion
#region Metotlar
public Arama()
{
InitializeComponent();
ingilizceSecim.Select();
Baglanti = new SqlConnection(baglantiCumlesi);
Duzenle();
}
private void Duzenle()
{
kelimeGiris.Select();
kelimeGiris.SelectionStart = 0;
sonucListe.Items.Clear();
}
private void Cikis_Click(object sender, EventArgs e)
{
this.Close();
}
#endregion
#region Giriş alanı
private void KayitIsle(object sender, EventArgs e)
{
string girdi;
#region İngilizce seçim
if (ingilizceSecim.Checked)
{
#region Sorgu alanı
#region Girdi kontrol
if (!kelimeGiris.Text.Equals(String.Empty))
girdi = kelimeGiris.Text.ToLower();
else
{
MessageBox.
Show("Lütfen İngilizce kelime alanını boş bırakmayınız.",
"Boş alan",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
Duzenle();
return;
}
#endregion
#region Bağlantı
Baglanti.Open();
#region Sorgu
using (Sorgu = new SqlCommand(ingilizceSorgusu, Baglanti))
{
Sorgu.Parameters.AddWithValue("@deger", girdi);
Sorgu.CommandType = CommandType.Text;
Okuyucu = Sorgu.ExecuteReader();
// Can't retrieve data into ListBox here
while (Okuyucu.Read())
sonucListe.Items.Add(Okuyucu["Anlam"].ToString());
Okuyucu.Close();
}
#endregion
Baglanti.Close();
#endregion
#endregion
return;
}
#endregion
#region Türkçe seçim
if (turkceSecim.Checked)
{
#region Sorgu alanı
if (!kelimeGiris.Text.Equals(String.Empty))
girdi = kelimeGiris.Text.ToLower();
else
{
MessageBox.Show("Lütfen Türkçe kelime alanını boş bırakmayınız.",
"Boş alan",
MessageBoxButtons.OK,
MessageBoxIcon.Error,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.ServiceNotification);
Duzenle();
return;
}
#region Bağlantı
using (Baglanti = new SqlConnection(baglantiCumlesi))
{
Baglanti.Open();
#region Sorgu
using (Sorgu = new SqlCommand(turkceSorgusu, Baglanti))
{
Sorgu.Parameters.AddWithValue("@deger", girdi);
#region Sonuç aktarma
using (Okuyucu = Sorgu.ExecuteReader())
{
}
#endregion
}
#endregion
Baglanti.Close();
}
#endregion
#endregion
return;
}
#endregion
}
#endregion
#region Dil tercih değişim
private void ingilizceSecim_CheckedChanged(object sender, EventArgs e)
{
kelimeBaslik.Text = "İngilizce";
anlamBaslik.Text = "Türkçe";
}
private void turkceSecim_CheckedChanged(object sender, EventArgs e)
{
kelimeBaslik.Text = "Türkçe";
anlamBaslik.Text = "İngilizce";
}
#endregion
}
}
这与ADO.NET无关。如果在 SSMS 中执行,该查询也不会 return 任何结果。这是因为 LIKE '@deger%'
搜索以字符 @deger
开头的字符串。
查询参数类似于 函数 参数 - 它们不会注入到查询字符串中,而是作为 ... 值传递给已编译的查询。当客户端执行带参数的查询时,这些参数将发送到 外部 查询。这就是参数化查询不易受到 SQL 注入攻击的原因——值永远不会成为查询的一部分。 (除非开发人员特意重新引入该风险)。
在 SSMS 或存储过程中,正确的查询如下所示:
define @deger varchar(20)='whatever%'
SELECT [KA].[Anlam]
FROM [KelimeAnlam] [KA]
LEFT OUTER JOIN [IngKelimeler] [IK] ON [KA].[KelimeID] = [IK].[ID]
WHERE [IK].[Kelime] LIKE @deger
或
define @deger varchar(20)='whatever'
SELECT [KA].[Anlam]
FROM [KelimeAnlam] [KA]
LEFT OUTER JOIN [IngKelimeler] [IK] ON [KA].[KelimeID] = [IK].[ID]
WHERE [IK].[Kelime] LIKE @deger + '%'
查询字符串也必须使用其中一种形式,例如:
var ingilizceSorgusu = "SELECT [KA].[Anlam] " +
"FROM [KelimeAnlam] [KA] " +
"LEFT OUTER JOIN [IngKelimeler] [IK] ON [KA].[KelimeID] = [IK].[ID] " +
"WHERE [IK].[Kelime] LIKE @deger + '%'";