I'm trying to build a query that can give me the different rows between two tables.
Here is my code:
try
{
string searchquery = "SELECT* FROM NewList EXCEPT SELECT* FROM Restaurants UNION All";
SqlCommand searchcom = new SqlCommand(searchquery, connection);
SqlDataAdapter da = new SqlDataAdapter(searchcom);
DataSet ds = new DataSet();
connection.Open();
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
connection.Close();
}
catch (Exception er)
{
Debug.WriteLine(er.Message);
return;
}
I get the following error:
Incorrect syntax near 'All'.
What is the correct way/syntax to use Union All in SqlCommand class? I've tried to put it it my query string in too many ways but it's giving me the same error every time. How can I implement it in my search query with correct syntax ?
Your query is incorrect from UNION ALL on.
You can try it like this:
string searchquery = "SELECT * FROM NewList UNION ALL SELECT * FROM Restaurants ";
However, you need to be aware that:
It does not remove duplicate rows between the various SELECT statements (all rows are returned)
Each SELECT statement within the UNION ALL must have the same number of columns in the result sets with similar data types
Read here for more details.
Updated
You should use EXCEPT instead of UNION ALL if you want to get rows in one table that are not present in the other one.
Select Checking.RestID, FROM
(SELECT RestID FROM NewList EXCEPT Select RestID from Restaurants) as Checking
LEFT JOIN NewList ON Checking.RestID = NewList.RestID
this worked, thanks to anyone !
Related
Thank you in advance for any advice you are able to give me.
What I'm trying to achieve: I have a combobox that I want to populate with table1 / columnC, sorted by matches in table1 / columnB and table2 / columnB.
For example: I want to display all of Roberts potatoes, not everyone's potatoes.
I have created a stored procedure for this. It currently looks like this:
CREATE PROCEDURE [dbo].[myProcedure]
#myParameter nvarchar
AS
SELECT columnA, columnB, columnC
FROM table1
INNER JOIN table2 ON table1.columnB = table2.columnB
WHERE table1.columnB = #myParameter
Data set:
DataSet MyDataSet()
{
DataSet ds = new DataSet();
using (SqlConnection con = new SqlConnection(connectionString))
using (SqlDataAdapter da = new SqlDataAdapater("myProcedure", con))
{
da.SelectCommand.CommandType = CommandType.StoredProcedure;
//the line below gives value to my parameter, which in this case is a WinForms label
//with the table1/columnB, table2/columnB value (the name that I wish to sort by)
da.SelectCommand.Parameters.Add("#myParameter", SqlDbType.NVarChar).Value = label.Text.ToString();
da.Fill(ds);
}
return ds;
}
Populating my combobox (code is in form load event):
try
{
DataSet ds2 = MyDataSet();
myComboBox.DataSource = ds2.Tables[0];
myComboBox.DisplayMember = "columnC";
myComboBox.ValueMember = "columnA"; // hidden ID row
}
catch (Exception ex)
{
// messageboxcode
}
Oh, and, if it matters, all my columns are nvarchar except for table1/columnA, which is int.
Hope I make sense and that someone is able to give me a hint or two.
In regards to what I've tried to fix this, being new to SQL, I have read documentation, watched tutorials and generally spent hours trying to figure this out. I just can't for some reason! :-)
I can say that your stored procedure is malformed because you don't have a length on nvarchar(). Never use char and related types in SQL Server without a length parameter.. The default varies by context and assuming the default does what you want just leads to hard to debug errors (ahem).
In the absence of other information, you can use (max), but I would suggest that you use an appropriate value for the length of the parameter:
CREATE PROCEDURE [dbo].myProcedure (
#myParameter nvarchar(max)
) AS
BEGIN
SELECT columnA, columnB, columnC
FROM table1 JOIN
table2
ON table1.columnB = table2.columnB
WHERE table1.columnB = #myParameter;
END;
Add the order like:
order by table1.columnB,table2.columnB
I am trying to execute multiple SELECT statements, such as,
DataSet ds = new DataSet();
string sql = #"SELECT * FROM CUSTOMERS;
SELECT * FROM CUSTOMERS WHERE AGE > 40;";
using (FbConnection connection = new FbConnection(ConectionString))
{
try
{
using (FbCommand cmd = connection.CreateCommand())
using (FbDataAdapter sda = new FbDataAdapter(cmd))
{
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
connection.Open();
sda.Fill(ds);
}
}
catch (FbException e)
{
Error = e.Message;
}
finally
{
connection.Close();
}
}
return ds;
The above code works great for one SELECT statement, but it throws an exception when there are multiple SELECT statements.
Dynamic SQL Error
SQL error code = -104
Token unknown - line 2, column 1
SELECT
I have tried the FbBatchExecution as well but I don't know how to get the returned data from it. It works well when using multiple INSERT or DELETE statements.
You have to build ONE query out of those two using SQL UNION operator
https://en.wikipedia.org/wiki/Set_operations_(SQL)#UNION_operator
https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-select.html#fblangref25-dml-select-union
Note how these your queries fetch the same rows: the first query has all the rows of the second plus some more
SELECT * FROM CUSTOMERS;
SELECT * FROM CUSTOMERS WHERE AGE > 40;
Basically you have two ways to link them together
SELECT * FROM CUSTOMERS
UNION ALL
SELECT * FROM CUSTOMERS WHERE AGE > 40
and
SELECT * FROM CUSTOMERS
UNION DISTINCT
SELECT * FROM CUSTOMERS WHERE AGE > 40
The first option would just link one query after another, without caring what the data they have brought. And unless you add ORDER BY clause it also would most probably keep the order of rows produced by sequential queries, just because it is easier to do so. However there is no warranty on that in neither SQL standard nor Firebird documentation, in other words that is purely "implementation detail" and there is some chance that in future rows would get reordered interleaving the queries even with UNION ALL w/o ORDER BY link (for example if the subqueries would be spawn into different processors for parallelization).
The second option would sort the outputs in temporary buffers and exclude duplicates, which would mean more working time for the server and more volume in memory and/or disk used for that temporary buffers and sorting, but would ensure you do not have duplicates in the rows (which means your specific queries would have then the same set of data as the first query alone).
Contrary to SQL Server, Firebird doesn't support execution of multiple statements in a single execute, nor can a single execute produce multiple result sets. If you want to execute multiple statements, you will need to execute them individually.
You also can't use FbBatchExecution because that is for executing inserts, updates, deletes, etc (statements that don't produce a result set).
I dont know FbConnection provider, but if implement IDbConnection, so you can maybe use Dapper and then your problem solve this:
https://dapper-tutorial.net/querymultiple
string sql = "SELECT * FROM Invoice WHERE InvoiceID = #InvoiceID; SELECT * FROM InvoiceItem WHERE InvoiceID = #InvoiceID;";
using (var connection = My.ConnectionFactory())
{
connection.Open();
using (var multi = connection.QueryMultiple(sql, new {InvoiceID = 1}))
{
var invoice = multi.Read<Invoice>().First();
var invoiceItems = multi.Read<InvoiceItem>().ToList();
}
}
Try this:
using (SqlConnection sql = new SqlConnection(key))
{
try
{
sql.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = #"SELECT * FROM CUSTOMERS;
SELECT * FROM CUSTOMERS WHERE AGE > 40;";
cmd.Connection = sql;
var dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
//First query data
}
if (dr.NextResult())
{
if (dr.HasRows)
{
while (dr.Read())
{
//Second Query Data
}
}
}
}
}
catch (FbException e)
{
Error = e.Message;
}
finally
{
sql .Close();
}
}
I'm working on a project and I add a query on navicat that displayed the results I wanted perfectly but when I used that same query on my project it only showed 5 rows of results.
the code im using for filling the datagridview and fetching the data is the following.
string cs = "*info*";
MySqlConnection liga = new MySqlConnection(cs);
string query = "*I have the full query futher down, its big and it looks stange in here*";
MySqlCommand comando = new MySqlCommand(query, liga);
int nInt = Convert.ToInt32(textBox1.Text);
comando.Parameters.AddWithValue("#ni", nInt);
try
{
liga.Open();
MySqlDataReader leitor = comando.ExecuteReader();
DataTable tabela = new DataTable();
tabela.Load(leitor);
dataGridView1.DataSource = tabela;
leitor.Close();
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
liga.Close();
}
QUERY
SELECT
disciplinas.nome AS Disciplina,
mods_alunos.numero,
mods_alunos.nota
FROM
mods_alunos
INNER JOIN disciplinas ON mods_alunos.codDisc = disciplinas.codDisc
WHERE
nInterno = #ni
I've come to the conclusion that it has to do with the INNER JOIN because is i just do SELECT * FROM mods_alunos it displays more than 5 results
EDIT 1:
You should consider using an LEFT OUTER JOIN instead of INNER JOIN like
SELECT
disciplinas.nome AS Disciplina,
mods_alunos.numero,
mods_alunos.nota
FROM mods_alunos
LEFT OUTER JOIN disciplinas ON mods_alunos.codDisc = disciplinas.codDisc
WHERE nInterno = #ni
You have used ExecuteReader method which returns only 1 row at a time.
You can use ExecuteScalar method which returns a complete table which can be used to fill Gridview.
I have a part of code, which returns non distinct values.
Is there anyway, I could use a distinct function to the same to get distinct values?
Code:
public static Recordset queryTestDirector(string projectName, string query)
{
Recordset result = null;
/*Connect to Test director and pull down all the currently listed QC numbers*/
TDConnection tdConnection;
tdConnection = new TDAPIOLELib.TDConnection();
tdConnection.InitConnection("http://***/qcbin/", "ABC", "");
tdConnection.ConnectProject(projectName, "qc_manager", "");
Command cmd;
cmd = tdConnection.Command as Command;
String qcIDQuery = query;
cmd.CommandText = qcIDQuery;
result = cmd.Execute() as Recordset;
tdConnection.Disconnect();
return result;
}
The problem is the result returned gives values:
A,A,A,A,B,C,D
I want only A,B,C,D
Please suggest.
Changing your query to
select distinct BG_USER_50 from BUG where BG_STATUS in ('In Progress','Fixed','Unit Testing','Ready For UAT') and BG_USER_50 is not null order by BG_BUG_ID desc
should solve your problem
Haven't tried it, but this might work. You'll first have to convert your recordset into a dataset
ds.Tables[0].DefaultView.ToTable(true,"BG_USER_50");
Here's a link explaining more
http://www.c-sharpcorner.com/blogs/230/how-to-get-disticnt-rows-from-a-dataset-or-datatable.aspx
How to select distinct rows in a datatable and store into an array
Thanks a lot guys for your inputs, which made me rethink the query.
Finally this query works:
queryString = "select BG_USER_50, count(*) from BUG where BG_STATUS in ('In Progress','Fixed','Unit Testing','Ready For UAT') and BG_USER_50 is not null group by BG_USER_50 order by 1 desc"
I just needed a Group by clause.
How to check if my table is empty from C#?
I have something like:
public MySqlConnection con;
public MySqlCommand cmd;
con = new MySqlConnection(GetConnectionString());
con.Open();
cmd = new MySqlCommand("SELECT * FROM data;", con);
Or I don't need to call SELECT statement?
You can use COUNT(*) with no WHERE close and see if exactly how many rows exist with the result.
Or you can do a SELECT (id) FROM tablename with no WHERE clause and if no rows are returned then the table is empty.
I'll give you an example in C# good luck
public bool checkEmptyTable(){
try
{
MySql.Data.MySqlClient.MySqlCommand com = new MySql.Data.MySqlClient.MySqlCommand();
conn = new MySql.Data.MySqlClient.MySqlConnection("YOUR CONNECTION");
com.Connection = conn;
com.CommandText = "SELECT COUNT(*) from data";
int result = int.Parse(com.ExecuteScalar().ToString());
return result == 0; // if result equals zero, then the table is empty
}
finally
{
conn.Close();
}
}
If 'data' might be a big table you would be better with this (where pkdata is your primary key field)
SELECT COUNT(*) FROM data WHERE pkdata = (SELECT pkdata FROM data LIMIT 1);
This will run very quickly whether you have 0 rows in 'data' or millions of rows. Using SELECT with no WHERE or ORDER BY means it just pulls the first row available, LIMIT 1 stops it getting more than 1.
Maybe something to look for if you have a program that ran very quickly six months ago but now runs like a dog in treacle!
SELECT COUNT(*)
FROM table
WHERE `col_name` IS NOT NULL