注意:我的办公室不允许我查看YouTube和其他几个可能对这个问题有答案的网站(它们被阻止),这就是谷歌搜索答案的原因结果。
ComboBox代码参考:found here
在我的C# Form
上,我用一个数据库中的表填充了一个ComboBox(参见下面的代码),它正确地返回了相应的值和函数:
public Form1()
{
InitializeComponent();
// Connection
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "CONNECTION STRING" // shortened for security and convenience
// Fill ComboBox with SQL Values
conn.Open();
SqlCommand cmbTables = new SqlCommand("SELECT name FROM sys.tables", conn);
SqlDataReader read = cmbTables.ExecuteReader();
DataTable cmbData = new DataTable();
cmbData.Columns.Add("name", typeof(string));
cmbData.Load(read);
cmb1.DisplayMember = "name";
cmb1.DataSource = cmbData;
conn.Close();
}
在ComboBox
加载表(工作正常)之后,应用程序然后选择一个表并单击一个加载表的按钮,该按钮被选中。这是代码错误的地方:
private void button1_Click(object sender, EventArgs e)
{
using (var connection = Utilities.GetConnection())
{
string table = Convert.ToString(txt1.Text);
string cmb1Value = Convert.ToString(cmb1.SelectedItem);
// Stored Procedure
SqlCommand select = new SqlCommand("EXECUTE STOREDPROCEDURE" + cmb1Value, connection); // shortened for security and convenience
select.Parameters.Add(new SqlParameter(cmb1Value, table));
// Data View
SqlDataAdapter ad= new SqlDataAdapter(select);
ad.SelectCommand = select;
DataTable dt = new DataTable();
ad.Fill(dt); // this generates the error "Incorrect Syntax Near '.'"
BindingSource b = new BindingSource();
b.DataSource = dt;
dGrid.DataSource = b;
ad.Update(dt);
connection.Close();
}
}
即使ComboBox加载了适当的值,从上面的代码中,我可能会遗漏一些将这些值附加到SELECT
存储过程的东西(它所做的就是通过变量调用SELECT
语句传递给它)。错误"Incorrect Syntax Near '.'"
看起来像我看到的SQL Server
错误,但不记得我是如何生成它的(这是我通常在TSQL
代码出错的地方遇到的问题) \
存储过程相关代码:
C#:
SqlCommand select = new SqlCommand("EXECUTE STOREDPROCEDURE " + cmb1Value, connection);
TSQL:
CREATE PROCEDURE [STOREDPROCEDURE]
@TableName VARCHAR(250)
AS
BEGIN
DECLARE @sql NVARCHAR(MAX)
SET @sql = N'SELECT TOP 100 *
FROM ' + @TableName
EXECUTE(@sql)
END
-- Note this works in SSMS without a problem.
上面的代码不正确,当我调整TSQL
代码时,我会生成类似的错误,告诉我某个地方我错过了转化或其他变量,因为SQL Server
没有看到这些SELECT
(第一个代码块)返回的表值。我可以确定这一点,因为我有第二个使用类似代码 EXCEPT 的ComboBox,我用手工值填充了ComboBox,它连接到数据库中的表而没有错误。因此,从上面看到的从数据库中获取值的ComboBox无法正常运行。
例如,如果我只在代码中添加以下代码行,我收到一个错误,它无法找到数据库“EXECUTE STOREDPROCEDURE System”
select.CommandType = CommandType.StoredProcedure;
然而,System
不是任何事物的一部分,那么它来自哪里?它从来没有在手动ComboBox上使用此代码,因为它可以轻松找到数据库(使用相同的连接字符串,服务器和数据库!)。
如果我尝试使用TSQL参数,例如:
SqlCommand select = new SqlCommand("EXECUTE stp_ReturnTable @p", scon);
select.Parameters.Add(new SqlParameter("@p", cmb1Value));
突然间,找不到存储过程。同样,手动ComboBox和动态ComboBox的连接字符串相同。
我认为动态ComboBox背后的代码是错误的。当我不在办公室时,我将回顾一些视频,详细演示如何从数据库创建动态ComboBox,我有一个系统对象阻碍的预感(基于系统错误,存在在我的代码中没有任何地方,以及它突然无法找到数据库或程序)。
答案 0 :(得分:8)
代码中缺少的关键点是CommandType 没有这个属性的正确集合,默认是CommandText,因此Framework需要一个以SELECT / INSERT / UPDATE / DELETE等开头的语句....
using (var connection = Utilities.GetConnection())
{
string table = Convert.ToString(txt1.Text);
string cmb1Value = Convert.ToString(cmb1.SelectedItem);
// Stored Procedure
SqlCommand select = new SqlCommand("STOREDPROCEDURE", connection);
select.Parameters.Add(new SqlParameter("@TableName", cmb1Value));
// That's the key to let ADO.NET accept the previous CommandText as valid.
// If you omit this the CommandText is assumed to be a SELECT/UPDATE/DELETE etc..
select.CommandType = CommandType.StoredProcedure;
// Data View
SqlDataAdapter ad= new SqlDataAdapter(select);
DataTable dt = new DataTable();
ad.Fill(dt);
BindingSource b = new BindingSource();
b.DataSource = dt;
dGrid.DataSource = b;
}
编辑看过SP的代码后,您只需将SqlParameter名称设置为常量@TableName
,并将从组合框中提取的值作为要在其中使用的值传递。 SP
编辑我再次查看了您的代码,我怀疑罪魁祸首是
string cmb1Value = Convert.ToString(cmb1.SelectedItem);
看看你如何填充你的组合,这一行不会像你期望的那样返回表名,而是返回通用字符串System.Data.DataRowView
,因为组合的DataSource是一个DataTable而不是一个字符串集合。您应该尝试以这种方式更改该行
DataRowView rw = cmb1.SelectedItem as DataRowView;
if(rw != null)
{
string cmbValue1 = rw["name"].ToString();
....
是的,您的代码也可以在没有CommandType.StoredProcedure
行的情况下工作,因为文本EXECUTE sp param
被识别为有效的sql命令文本(但是为什么在直接调用storedprocedure时可以使用它优化再利用?)