0

Using Visual Studio 2017, I'm trying to build a Windows Forms application that asks a user for specific value from a SQL Server Express database (footballteam).

User enters a value (@jnumber) in a text box (textBox1.Text) which corresponds to the "LIKE" for "JERSEYNUMBER".

Then, the query (commandText) is to be executed after clicking on button (button1_Click)

Results should display a DataGridView.

Build results were: "Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped".

However, when running the application, user enters a number value for @jnumber in textBox.Text, then clicks on button (button1_Click), but dataGridView1 remains empty; no results.

Goal is also to avoid SQL injection. Appreciate your help.

Code is here:

// directives
using System;
using System.Data
using System.Windows.Forms;
using System.Data.SqlClient;

namespace displaydmlquery
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // variable sql query
            var commandText = "SELECT * FROM JERSEY WHERE JERSEYNUMBER LIKE '%' + @jnumber+ '%' ORDER BY ASSIGNMENT_DATE";
            // variable connection string
            var connectionString = "Server=hostname\\SQLEXPRESS;Database=footballteam;User Id=userid;Password=password";

            // Create a connection instance
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                // Create a SqlCommand instance
                SqlCommand command = new SqlCommand(commandText, connection);

                // Add the parameter to used in the text box input
                command.Parameters.Add("@jnumber", SqlDbType.NVarChar, 20).Value = textBox1.Text;

                // Execute query
                try
                {
                    // open connection
                    connection.Open();

                    // create a SqlDataAdapter to execute query
                    var dataAdapter = new SqlDataAdapter(commandText, connectionString);

                    // Create command builder
                    var commandBuilder = new SqlCommandBuilder(dataAdapter);

                    // Execute query reader
                    command.ExecuteReader();

                    // create a data table to hold query
                    DataTable dtRecord = new DataTable();

                    // fill in data tbale
                    sqlDataAdap.Fill(dtRecord);

                    // Display results in  DataGridView
                    dataGridView1.DataSource = dtRecord;
                }
                catch
                {
                    // Handle exception, future code
                }
                finally
                {
                    connection.Close();
                }
            }
        }
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Ben Q
  • 187
  • 1
  • 1
  • 15
  • 1
    `new SqlDataAdapter(commandText ` should be `new SqlDataAdapter(command` – Conrad Frix Jan 08 '18 at 19:38
  • A much easier way is to load the DataTable with all Jersey number and just filter it as desired. Hitting the server repeatedly is rather inefficient – Ňɏssa Pøngjǣrdenlarp Jan 08 '18 at 19:40
  • I just realized it's more than that what I previously wrote. sqlDataAdap which fills the table isn't defined in your coding snippit so I have no idea what it's doing. – Conrad Frix Jan 08 '18 at 19:45
  • `dataGridView1.Refresh()` try that see if it refreshes the datagridview – MethodMan Jan 08 '18 at 19:53
  • First of all you sql appears to be just fine. The code however is crippling your ability to function. You have an anti-pattern I call try/squelch. Which is, you have a catch that does nothing expect capture any error and throw it away and pretend like nothing happened. Get that catch out of your code. – Sean Lange Jan 08 '18 at 20:22
  • @ConradFrix Thank you, I tried as suggested: `var dataAdapter = new SqlDataAdapter(command);` but no fortune. – Ben Q Jan 08 '18 at 20:25
  • @Plutonix Thank you. Very good idea. But I don't how to code that, "load DataTable". I will try to figure it out next. – Ben Q Jan 08 '18 at 20:27
  • @ConradFrix Thank you. I just defined "sqlDataAdap": `var sqlDataAdap = new SqlDataAdapter(); // fill in data tbale sqlDataAdap.Fill(dtRecord);` . Then, debugged application. But same result. Built ok. but no results dataGridView1 – Ben Q Jan 08 '18 at 20:30
  • @MethodMan Thank you. I added "dataGridView1. Refresh()" as suggested. ' // Display results in DataGridView dataGridView1.DataSource = dtRecord; dataGridView1.Refresh();` Application built ok. But same result, no display in dataGridView – Ben Q Jan 08 '18 at 20:30
  • Your code is already loading a datatable - filtering them is easily researched – Ňɏssa Pøngjǣrdenlarp Jan 08 '18 at 20:31
  • Get that catch out of there. You may be getting an error which is why your grid is empty. You don't need that finally anyway because your connection is properly wrapped in a USING statement. It will be closed and disposed at the end of that statement. – Sean Lange Jan 08 '18 at 20:33
  • Is the button click event wired up? This is a debugging problem. Step through your code and see what happens. – LarsTech Jan 08 '18 at 20:44
  • Your code for populating your data is all over the place. You have variables being created that are not used. You have things like ExecuteReader not being assigned to anything (the point of that method is return a SqlDataReader). – Sean Lange Jan 08 '18 at 20:52
  • Thank you All for your help. Problem solved. Please see last comment below. Again, thank you All. – Ben Q Jan 09 '18 at 01:20

2 Answers2

3

I was trying to hint at what your problems were in the comments but I failed so I'm taking the time to give you a complete answer.

Below is what your code is doing. You'll notice that some of the lines have question marks. These are the troubling lines because they don't make any sense. It seems you're confusing what the different data objects are meant to do.

 1. set up a sql string
 2. set up a connection string
 3. create a connection Object from connection string from (2)
 4. create a command Object from the sql string and the connection object from (1) and (3) 
 5. set the value of the parameter on the command object from (4)
 6. open the connection Object from (3)
 7. create a DataAdapter object and a new connection Object (???) 
     and a new command Object (???) from (1) and (3)        
 8. create commandBuilder and generate INSERT UPDATE and DELETE commands Objects (???) from the data adapter (7)  
 9. execute the command object from (4). Disregard the results (???)
 10. create a new DataTable Object
 11. fill the DataTable from (10) with an unknown sqlDataAdap (does it have 
       connection, sql, or parameters associated ????)
 12. set the DataSource on the datagrid to the filled(?) datatable from (10)        
 13. throw away exceptions (???)
 14. close the connection
 15. dispose the connection

Here's some code that should work

using (SqlConnection connection = new SqlConnection(connectionString))
{

    // Create a SqlCommand instance
    SqlCommand command = new SqlCommand(commandText, connection);

    // Add the parameter to used in the text box input
    command.Parameters.Add("@jnumber", SqlDbType.NVarChar, 20).Value = textBox1.Text;


    // open connection
    connection.Open();

    // create a SqlDataAdapter using the command object with the parameters set
    var dataAdapter = new SqlDataAdapter(command, connectionString);

    // create a data table to hold query
    DataTable dtRecord = new DataTable();

    // fill in data table with the dataAdapater
    dataAdapter.Fill(dtRecord);

    // Display results in  DataGridView
    dataGridView1.DataSource = dtRecord;
} // Using will close the connection when it disposes it
Conrad Frix
  • 51,984
  • 12
  • 96
  • 155
  • Conrad Frix + All. Thank you. It worked. For `var dataAdapter = new SqlDataAdapter(command);` Also, I made two mistakes. 1) I made a typo in the database name in my actual code. 2) I was impatient not waiting enough for debugger to complete as it pointed "1)" out this error. Again, thank you. – Ben Q Jan 09 '18 at 01:16
0

Please try with updating your query

        // variable sql query
        var commandText = "SELECT * FROM JERSEY WHERE JERSEYNUMBER LIKE '%'  @jnumber '%' ORDER BY ASSIGNMENT_DATE";

and add parameter as you are already doing....

Ehsan Ullah Nazir
  • 1,827
  • 1
  • 14
  • 20
  • you need to concatenate the wildcards and the parameter. – Sean Lange Jan 08 '18 at 19:58
  • you mean like `"SELECT * FROM JERSEY WHERE JERSEYNUMBER LIKE '%' " + @jnumber + " '%' ORDER BY ASSIGNMENT_DATE";` ? – Ehsan Ullah Nazir Jan 08 '18 at 20:12
  • 1
    NO!!! That would circumvent using parameters. It would be like this. "SELECT * FROM JERSEY WHERE JERSEYNUMBER LIKE '%' + @jnumber + '%' ORDER BY ASSIGNMENT_DATE" – Sean Lange Jan 08 '18 at 20:16
  • thats what he is already doing, please view link [parameterized query](https://stackoverflow.com/questions/7505808/why-do-we-always-prefer-using-parameters-in-sql-statements) – Ehsan Ullah Nazir Jan 08 '18 at 20:20
  • Right and the sql they posted is correct. The issue is that the grid is empty. – Sean Lange Jan 08 '18 at 20:21
  • i think the problem is with query , and **@jnumber** will be resolved when query will be executed. `command.Parameters.Add("@jnumber", SqlDbType.NVarChar, 20).Value = textBox1.Text;` ` added parameter should be spelled same as its in query.though i haven't testing this at my end. – Ehsan Ullah Nazir Jan 08 '18 at 20:24
  • Not sure what you mean. The named parameter and the code do match. – Sean Lange Jan 08 '18 at 20:35
  • I meant that parameter that we are adding in `command.Parameters.Add` – Ehsan Ullah Nazir Jan 08 '18 at 20:39
  • @EhsanUllahNazir Thank you. I tried your suggestions. App built ok. But same result. No dataGridView results – Ben Q Jan 08 '18 at 20:44
  • Can you check either your query is returning records or not?If yes , then there is some issue with binding result set to grid. – Ehsan Ullah Nazir Jan 08 '18 at 20:46
  • @SeanLange Thank you. I tried your suggestions. App built ok, but same result. No dataGridView results. Question: the "@jnumber" is an integer value, and using `"SqlDbType.NVChar, 20`, should be fine, right? Thanks. – Ben Q Jan 08 '18 at 20:47
  • Put break point on `sqlDataAdap.Fill(dtRecord);` and look for records. – Ehsan Ullah Nazir Jan 08 '18 at 20:47
  • @EhsanUllahNazir. yes it returns records OK. . as a test, I'm also using Microsoft SQL Manager Studio". For example, this query ran ok `SELECT * FROM JERSEY WHERE JERSEYNUMBER like '%2%';` – Ben Q Jan 08 '18 at 20:54
  • If query is returning record that means data is not binding with grid.Can you share that code lines as well? – Ehsan Ullah Nazir Jan 08 '18 at 20:58