注意:我的办公室不允许我查看YouTube和其他几个可能对这个问题有答案的网站(它们被阻止),这就是谷歌搜索答案没有产生结果的原因.
ComboBox代码参考:在这里找到
在我的上面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();
}
Run Code Online (Sandbox Code Playgroud)
在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();
}
}
Run Code Online (Sandbox Code Playgroud)
即使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.
Run Code Online (Sandbox Code Playgroud)
上面的代码是不正确的,当我调整TSQL代码时,我生成类似的错误,告诉我某个地方我错过了转换,或者另一个变量,因为SQL Server没有看到SELECT(第一个代码块)返回的这些表值.我可以确定这一点,因为我有第二个ComboBox,它使用类似的代码EXCEPT,我使用手动值填充ComboBox,并且它连接到数据库中的表而没有错误.因此,您在上面看到的从数据库中获取值的ComboBox无法正常运行.
例如,如果我只将下面的代码行添加到代码中,我收到一个错误,它无法找到数据库"EXECUTE STOREDPROCEDURE System"
select.CommandType = CommandType.StoredProcedure;
Run Code Online (Sandbox Code Playgroud)
但是,System它不是任何东西的一部分,那么它是从哪里来的?它从来没有在手动ComboBox上使用此代码,因为它可以轻松找到数据库(使用相同的连接字符串,服务器和数据库!).
如果我尝试使用TSQL参数,例如:
SqlCommand select = new SqlCommand("EXECUTE stp_ReturnTable @p", scon);
select.Parameters.Add(new SqlParameter("@p", cmb1Value));
Run Code Online (Sandbox Code Playgroud)
突然间,它找不到存储过程.同样,手动ComboBox和动态ComboBox的连接字符串相同.
我认为动态ComboBox背后的代码是错误的.当我不在办公室时,我将回顾一些视频,详细演示如何从数据库创建动态ComboBox,我有一个系统对象阻碍的预感(基于系统错误,存在在我的代码中没有任何地方,以及它突然无法找到数据库或程序).
代码中缺少的关键点是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;
}
Run Code Online (Sandbox Code Playgroud)
编辑看过SP的代码后,您可以简单地将SqlParameter名称设置为常量@TableName,并将从组合框中提取的值作为要在SP内部使用的值传递
编辑我再次看了你的代码,我怀疑罪魁祸首就是这条线
string cmb1Value = Convert.ToString(cmb1.SelectedItem);
Run Code Online (Sandbox Code Playgroud)
看看你如何填充你的组合,这一行不会像你期望的那样返回表名,而是返回通用字符串,System.Data.DataRowView因为组合的DataSource是一个DataTable而不是一个字符串集合.您应该尝试以这种方式更改该行
DataRowView rw = cmb1.SelectedItem as DataRowView;
if(rw != null)
{
string cmbValue1 = rw["name"].ToString();
....
Run Code Online (Sandbox Code Playgroud)
是的,您的代码也可以在没有CommandType.StoredProcedure行的情况下工作,因为文本EXECUTE sp param被识别为有效的sql命令文本(但是为什么在可以优化直接调用storedprocedure以供重用时使用它?)