【发布时间】:2017-05-31 12:37:47
【问题描述】:
我正在尝试运行依赖于参数的查询。
我以前用过它,它可以工作,但在这种情况下,似乎有一个问题,我无法理解。
我使用的是 SQL Server 2012。
这是我的代码:
public void getMissingKeys()
{
SqlConnection conn = new SqlConnection(_connection);
conn.Open();
foreach(DataRow dr in _result.Rows)
{
string sqlSearch = "SELECT TOP 1 [Column1],
[Column2], [Column3], [Column4], [Column5],
[Column6], [Column7], [Column8]
FROM KeyValuationActual_destination
WHERE [SystemType] = @system
AND [DataType] = @data
AND [Location] LIKE @location
AND [Department] LIKE @department
AND [Role] LIKE @role
AND [Language] LIKE @language
AND [Shift] LIKE @shift
AND [ResourceID] = @resource
AND [Activity] LIKE @activity AND
[Unique ID] IS NOT NULL";
SqlCommand cmd = new SqlCommand(sqlSearch, conn);
SqlParameter[] parameters = new SqlParameter[9];
parameters[0] = new SqlParameter("@system", SqlDbType.Float);
parameters[0].Value = dr["SystemType"];
parameters[1] = new SqlParameter("@data", SqlDbType.Float);
parameters[1].Value = dr["DataType"];
parameters[2] = new SqlParameter("@location", SqlDbType.VarChar, 255);
parameters[2].Value = dr["Location"].ToString();
parameters[3] = new SqlParameter("@department", SqlDbType.VarChar, 255);
parameters[3].Value = dr["Department"].ToString();
parameters[4] = new SqlParameter("@role", SqlDbType.VarChar, 255);
parameters[4].Value = dr["Role"].ToString();
parameters[5] = new SqlParameter("@language", SqlDbType.VarChar, 255);
parameters[5].Value = dr["Language"].ToString();
parameters[6] = new SqlParameter("@shift", SqlDbType.VarChar, 255);
parameters[6].Value = dr["Shift"].ToString();
parameters[7] = new SqlParameter("@resource", SqlDbType.Float);
parameters[7].Value = dr["ResourceID"];
parameters[8] = new SqlParameter("@activity", SqlDbType.VarChar, 255);
parameters[8].Value = dr["Activity"].ToString();
foreach (SqlParameter param in parameters)
{
cmd.Parameters.Add(param);
}
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
//Do something
}
}
conn.Close();
}
Column1..8 是虚构名称。
不知何故,我看到参数实际上被正确查询并返回,但SqlDataReader 似乎无法处理变量以在查询命令中“替换”它们。
所以reader.Read() 永远不会返回任何值。
我想知道它是否是参数类型(我也尝试对 VarChars 使用 nullables)。
在调试时,如果我检查 cmd 并前往“非公共成员”,我会看到两个错误:
EventSink = 'cmd.EventSink' 引发了“System.InvalidCastException”类型的异常
InternalSmiConnection = 'cmd.InternalSmiConnection' 引发了“System.InvalidCastException”类型的异常
我一直在到处寻找,但我不知道如何继续。
有什么想法吗?
更新
我最终设法完成了这项工作。
我已经放弃了 ExecuteReader,因为它不能检索行,甚至与 DataTable 结合使用。似乎如果你想使用参数它的字符串类型,并且由于表使用 Float 作为类型,这让我很头疼尝试匹配类型。
我结束了使用 SqlAdapater、DataTable 和参数。似乎参数的类型不是那么强,因为我不需要进行任何强制转换。
这就是我最终得到的代码:
public void getMissingKeys()
{
SqlConnection conn = new SqlConnection(_connection);
string sqlSearch = "SELECT TOP 1 "+
"[Column1], [Column2], [Column3], "+
"[Column4], [Column5], [Column6], "+
"[Column7], [Column8] "+
"FROM KeyValuationActual_destination "+
"WHERE [SystemType] = @system "+
"AND [DataType] = @data "+
"AND [Location] LIKE @location "+
"AND [Department] LIKE @department "+
"AND [Role] LIKE @role "+
"AND [Language] LIKE @language "+
"AND [Shift] LIKE @shift "+
"AND [Resource Utilisation Ref_ID] = @resource "+
"AND [Activity] LIKE @activity "+
"AND [Unique ID] IS NOT NULL";
try {
foreach (DataRow dr in _result.Rows)
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(sqlSearch, conn);
da.SelectCommand.Parameters.AddWithValue("@location", dr[2]);
da.SelectCommand.Parameters.AddWithValue("@department", dr[3]);
da.SelectCommand.Parameters.AddWithValue("@role", dr[4]);
da.SelectCommand.Parameters.AddWithValue("@language", dr[5]);
da.SelectCommand.Parameters.AddWithValue("@shift", dr[7]);
da.SelectCommand.Parameters.AddWithValue("@resource", dr[8]);
da.SelectCommand.Parameters.AddWithValue("@activity", dr[9]);
da.SelectCommand.Parameters.AddWithValue("@data", dr[10]);
da.SelectCommand.Parameters.AddWithValue("@system", dr[11]);
DataTable dataTable = new DataTable();
da.Fill(dataTable);
if(dataTable != null)
{
foreach(DataRow keyRow in dataTable.Rows)
{
dr[13] = keyRow["Column1"];
dr[14] = keyRow["Column2"];
dr[15] = keyRow["Column3"];
dr[16] = keyRow["Column4"];
dr[17] = keyRow["Column5"];
dr[18] = keyRow["Column6"];
dr[19] = keyRow["Column7"];
dr[20] = keyRow["Column8"];
}
}
conn.Close();
}
}
catch (Exception ex)
{
Console.WriteLine("Querying keys exception information! : {0}", ex);
}
}
如果您认为可以在此代码中改进某些内容,我愿意接受建议
【问题讨论】:
-
我注意到一些
likes 表达式,如果你在参数值或查询中不添加'%',它不会被视为喜欢,你认为这可能是问题所在? -
删除所有参数并运行查询。希望你会得到许多行中的第一行。一次添加一个参数,直到它“中断”
-
那些异常无关紧要,这只是调试器尽最大努力访问它可能访问的所有数据。您几乎总是会看到一些这样的例外情况,但这并不意味着它们一定是问题。我同意 kblok,如果您不使用通配符,
LIKEs 将被视为=。 -
AFAIK,
EventSink和InternalSmiConnection都是非公共成员,它们不常用于常规连接。在迭代内容之前使用HasRows检查SqlDataReader是否有结果。 -
@TetsuyaYamamoto,仅转发是一个问题吗?我从未听说过 SqlDataReader 的问题。
标签: c# sql sql-server-2012