1

An SQL query that I'm executing from my application is returning different results than SQL Management Studio, specifically missing entire rows of data.

I've tried stripping the query way down to just "SELECT *" from the relevant table with a single WHERE clause, this achieved the same result of the C# version missing the same row each time.

A stripped down SQL query (that still has the issue) looks like this

SELECT Token, Last_update, repeatno, Maxrepeatno, Dispwindowstart
FROM v_eps_prescriptions
WHERE Token='F69F4D-C82043-70379I'

The C# version is

SqlCommand command = new SqlCommand(
$@"SELECT Token, Last_update, messages, repeatno, Maxrepeatno
FROM v_eps_prescriptions
WHERE Token='{UUID}'",
conn);

The SQL version for this query will return 2 rows, C# will only return 1 row.

I've been putting the data into a dataGridView to debug which is where I'm seeing just the single row.

Edit: As requested the full chunk of C# that performs the query and what outputs to a datagrid (which is temporary for debugging)

try
{
    conn.ConnectionString = $"Data Source=[source];Initial Catalog=[Cat];Integrated Security=True";
    conn.Open();

    foreach (string UUID in ValidUUIDList)
    {
        try
        {
            DateTime dt = DateTime.Now.AddDays(1);
            DateTime dtpast = dt.AddMonths(-6);

            SqlCommand command = new SqlCommand(string.Format($@"SELECT Token, Last_update, messages, repeatno, Maxrepeatno
                                                                FROM [Table]
                                                                WHERE Token='{UUID}'
                                                                AND Dispwindowstart
                                                                BETWEEN '{dtpast.ToString("yyyy - MM - dd")} 00:00:00.000'
                                                                AND '{dt.ToString("yyyy-MM-dd")} 00:00:00.000'
                                                                OR Token='{UUID}'
                                                                AND Dispwindowstart IS NULL"),
                                                                    conn);

            using (SqlDataReader dataReader = command.ExecuteReader())
            {
                if (dataReader.Read())
                {
                    DataTable dataTable = new DataTable();
                    dataTable.Load(dataReader);
                    dataGridView1.DataSource = dataTable;
                }
            }
        }
        catch (Exception err)
        {
            MessageBox.Show($"An error occured while processing UUID {UUID}. \n\n{err.Message}");
        }
    }
}
catch (Exception err)
{
    MessageBox.Show($"An error occured while connecting to the Nexphase database. \n\n{err.Message}");
}
Ben R
  • 85
  • 6
  • 4
    Use the SQL Profiler and see what SQL query is generated when the C# version runs. – Thangadurai May 22 '19 at 09:50
  • @Thangadurai the query is correct, I've stepped through the code and taken the parsed query from the debugger and put that into the sql studio to work backwards and got the same result of 2 rows in sql and 1 with c# – Ben R May 22 '19 at 09:53
  • 1
    Check the `Database` names. both are connected to Same DB? – Shyam Vemula May 22 '19 at 09:55
  • @ShyamVemula both are the same yes, the destination only has one db – Ben R May 22 '19 at 09:55
  • Where are you seeing 1 row? in the grid view? There's a whole lot of code between what you've posted and grid view. Can you post the code that runs the command and also debug the returned dataset and see if you can get a count – Nick.Mc May 22 '19 at 09:56
  • Here's a whole bunch of suggestions for getting a rowcount https://stackoverflow.com/questions/5502863/sqldatareader-row-count/14629894 – Nick.Mc May 22 '19 at 09:57
  • Can you post the c# code where you read the results? – Hans Kilian May 22 '19 at 09:59
  • What is the type of `Token`? is it `nvarchar-something`? or `uniqueidentifier`? `uniqueidentifier` has very specific formatting rules (there are lots of ways of representing a UUID), and comparing a `uniqueidentifier` via a string can get hairy. If it is `uniqueidentifier`: does it work if you use an ADO.NET parameter with the value from a `Guid`? alternatively: what is the exact `CommandText` after your `$@"..."` token replacement has happened? – Marc Gravell May 22 '19 at 10:03
  • @HansKilian Code has been edited into original post – Ben R May 22 '19 at 10:12
  • @MarcGravell the Token isnt a unique field, multiple rows contain the same string which is what i want to return – Ben R May 22 '19 at 10:12
  • I would obfuscate sensitive data in your code btw. You have a partially qualified domain name, and database name in there – Matt Evans May 22 '19 at 10:13
  • @Nick.McDermaid Code has been edited into original post – Ben R May 22 '19 at 10:13
  • Do what @Thangadurai suggested. Attach Sql Profiler and capture the query that is sent with the parameters. You can copy/paste this into SSMS and execute it which should then easily show you why/where the differences are occurring. – Igor May 22 '19 at 10:14
  • @MatthewEvans thanks, i knew i would forget to do that even after reminding myself too... – Ben R May 22 '19 at 10:15
  • 2
    Try using `if (dataReader.HasRows)` rather than `if (dataReader.Read())`. I suspect Read removes the first row from the result set. – Hans Kilian May 22 '19 at 10:28
  • @HansKilian that nailed it, thats now returning all the rows i want (how frustrating that its just that) However now the datatable is closing the reader? – Ben R May 22 '19 at 10:36
  • SqlDataReader is a forward-only stream, so when `Load` reads through it, there's no way to get back to the beginning. – Hans Kilian May 22 '19 at 10:41
  • @HansKilian ok sure, i can work with this, i'm loading the data into the datagrid (might swap this to a dataset) so ill work from that instead of the reader, which i think is the more accepted protocol anyway? – Ben R May 22 '19 at 10:47

0 Answers0