C#ComboBox选择错误:“不正确的语法''''”

时间:2013-06-10 17:05:38

标签: c# combobox

注意:我的办公室不允许我查看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,我有一个系统对象阻碍的预感(基于系统错误,存在在我的代码中没有任何地方,以及它突然无法找到数据库或程序)。

1 个答案:

答案 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时可以使用它优化再利用?)