1

首先,请允许我向 StackOverFlow 的每一个人和所有用户转达我的问候和尊重。你们在帮助像我们这样的人方面做得很好。谢谢你。

现在我的问题是:我正在构建一个 winforms 应用程序,用于学习目的,它:1)连接到数据库并根据查询检索结果。2) 查询由以下任一方式生成: * 用户单击应用程序的各种控件或 * 用户自己编写查询然后执行它。3) 结果显示在结果框中。

我得到一个 SQLException "Incorrect syntax near'," 生成的语法是正确的,因为:1) 我复制了生成的查询并在 SQL Management Studio 中执行了它。它在那里完美地执行。2)我尝试手动编写查询然后执行它,但它仍然抛出相同的执行。

请注意,在应用程序开发的第一阶段,它只有三个控件,一个 DataGridView 控件、一个 TextBox 控件和一个 Button 控件。在那个阶段,我成功地生成了结果并展示了它们。在我添加了额外的功能后,应用程序停止了工作。我不明白为什么。我使用的是我在开发的第一阶段使用的相同代码,实际上它是相同的应用程序。因此,我使用前面提到的三个基本控件创建了另一个应用程序,并复制了主要应用程序生成的查询,然后在第二个应用程序中执行它。它在那里工作。

在当前阶段,如果我使用生成的查询或者我自己编写查询然后执行它,应用程序会抛出相同的执行。这是我的代码。当用户单击“执行”按钮时,将调用 LoadData 方法。

try
{

    string ConnectString = "Data Source=(local); Initial Catalog=AdventureWorks2008;User ID=; Password=;Integrated Security=SSPI";
    ConnectionObj.ConnectionString = ConnectString;//ConnectionObj is SQLConnection object defined in the same class as Loaddata()
    ConnectionObj.Open();
    ColumnNames = string.Empty;//ColumnNames is a String type defined in the same class as Loaddata()

    foreach (string Name in ColumnNamesCheckedListBox.CheckedItems)//ColumnNamesCheckedListBox is a CheckedListBox control which lets user select ColumnNames from the corresponding table
    {
        ColumnNames = ColumnNames + Name + ", ";
    }
    int Length = ColumnNames.Length;
    Length = Length - 2;//To remove the extra "," and "<space>" at the end of ColumnNames
    string TempQuery = ColumnNames.Remove(length);

    //User may use the query formed by the application or she may write her own query, hence using "string PossibleQuery"
    //SelectQueryDropDownList is a ComboBox control holding the items "Select" "Update" "Insert" and "Delete". Used to generate the DML clause in the query
    //Database_TreeView is a TreeView control that holds all the table names in the database. This is used to generate the "FROM" clause in the query
    //QueryBox is a TextBox control that displays the generated query and if required lets the user write her own query manually

    string PossibleQuery = SelectQueryDropDownList.SelectedItem.ToString() + TempQuery + " From " + Database_TreeView.SelectedNode.Name.ToString();
    QueryBox.TempQuery = PossibleQuery;
    string FinalQuery = QueryBox.Text; //incase the user modified the query at QueryBox manually

    SqlDataAdapter DA = new SqlDataAdapter(FinalQuery, ConnectString);
    SqlCommandBuilder CommandBuilder = new SqlCommandBuilder(DA);
    DataTable Table = new System.Data.DataTable();


    //EXCEPTION OCCURS AT THIS STATEMENT
    DA.Fill(Table);


    BindingSource Source = new BindingSource();
    Source.DataSource = Table;
    ResultBox.DataSource = Source;//ResultBox is a DataGridView control to display the results of the the query after execution (if any)
}
catch (Exception e)
{
MessageBox.Show(e.Message+"\nPlease try again","Error",MessageBoxButtons.OK);
}
finally
{
ConnectionObj.Close();
}

这是屏幕截图:这是我的应用程序生成的查询。 http://i60.photobucket.com/albums/h31/spiderclaws/Stack%20Over%20Flow/1ScreenShot2013-04-23at54453PM.png

这显示了生成的异常。 http://i60.photobucket.com/albums/h31/spiderclaws/Stack%20Over%20Flow/2ScreenShot2013-04-23at54550PM.png

请帮帮我。谢谢。问候, Gogol Prasad (Spiderclaws@gmail.com) PS-请原谅我写了这么长的帖子。我想让每个人都清楚。

[编辑]这是所要求的信息:请注意,我正在根据屏幕截图查询 Person.BusinessEntityContact ......

FinalQuery=Select BusinessEntityID, PersonID, ContactTypeID From Person.BusinessEntityContact

StackTrace info:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
   at ADOBasicsWinFormsApp.Form1.loaddata() in C:\Users\Gogol\Documents\Visual Studio 2010\Projects\ADOBasicsConsoleApp\ADOBasicsWinFormsApp\Form1.cs:line 684
4

2 回答 2

2

Looking at your image seems that a space is missing between SELECT and the first field

So add a space between the SelectedItem and TempQuery

 string PossibleQuery = SelectQueryDropDownList.SelectedItem.ToString() + " " +
                        TempQuery + " From " + Database_TreeView.SelectedNode.Name.ToString();

(I assume that SelectQueryDropDownList contains the word SELECT)

Apart from that I would suggest to use a StringBuilder to construct your column names

StringBuilder cols = new StringBuilder()
// A check here is required to avoid empty selections
foreach (string Name in ColumnNamesCheckedListBox.CheckedItems)
   cols.Append(Name + ",");
if(cols.Length > 0) cols.Length -= 2;
string TempQuery = cols.ToString();

Also the SqlConnection object created at the start of the method is not passed in to your DataAdapter and never used elsewhere, the SqlDataAdapter receive your connectionstring and so it manages the connection itself, meaning it opens the connection and it closes the connection. So you could remove it.

于 2013-04-23T14:24:31.787 回答
1

这里是

int length = ColumnNames.Length;
length = length - 2;
string TempQuery = ColumnNames.Remove(length);

将局部Length变量更改为小写l

或者您可以重写它以摆脱局部变量:

string TempQuery = ColumnNames.Remove(ColumnNames.Length - 2);
于 2013-04-23T14:14:12.830 回答