How to combine two SQLite statements running in C#? - c#

I have these two statements:
db2.Execute(" UPDATE CLICKHISTORY SET " +
" DAYOFYEAR = " + dayOfYear + " , " +
" YEAR = " + year + " , " +
" MONTH = " + month + " , " +
" DAY = " + day + " , " +
" BTNACOUNT = BTNACOUNT + 1 WHERE YYMMDD = " + yymmdd );
db2.Execute(" INSERT INTO CLICKHISTORY " +
" (YYMMDD,DAYOFYEAR,YEAR,MONTH,DAY,BTNACOUNT) " +
" VALUES ( " +
yymmdd + " , " +
dayOfYear + " , " +
year + " , " +
month + " , " +
day + " , " +
"1) WHERE changes() = 0");
What I would like to do is to check if changes() = 0 in the first statement before running the second statement.
Can anyone tell me how I can group together these two statements in to one so I can check the value of changes()?

Assuming db2 is of type SQLite.SQLiteConnection, you can use the return value of the Execute method to find out the number of affected rows - something like:
int rowsAffected = db2.Execute("UPDATE...");
if (rowsAffected == 0) {
rowsAffected = db2.Execute("INSERT...");
}

In general, you can combine sqlite statements using semicolon ;.
But as I understand, the real question here is: How to conditionally insert values in SQLite?
You cannot use WHERE with INSERT INTO table VALUES(...), but use can use INSERT INTO table SELECT ... syntax instead and add a WHERE clause to select.
Example
Let's say I have a simple table: scores (name varchar(20), score int). I want to update a row or insert a new one if there's nothing to update yet.
var name = "my team";
var sql = $"update scores set score = score+1 where name = '{name}';"
+ $"insert into scores(name, score) select '{name}', 0 where changes() = 0" ;
var cmd = new SQLiteCommand(sql, conn);
cmd.ExecuteNonQuery();
Depending on the driver you use, the C# methods used may differ - I'm using System.Data.Sqlite here.
You may also want to taka look at how to do Upsert in SQLite.

Related

update merge query with where clause in sql

note: i m importing data from sql sheet. and after this i want to insert data in a table but when it finds same ContractNo (contract number) it will update the data and when it finds different ContractNo ( contract number) it will insert as a new record
but my merge query is not working with where statement.
string mergeSql = "merge into " + tableName + " as Target " +
"using Ro_Consumers_Temp as Source " +
"on " +
"Target.ContractNo=Source.ContractNo " +
"when not matched then " +
"insert values (Source.Ronumber,Source.ContractNo,Source.BusinessPartner,Source.ContractAccount,Source.IBC,Source.Portion,Source.MRU,Source.Installation,Source.MeterNo,Source.LegacyNumber,Source.ConsumerNo,Source.ConsumerName,Source.Address,Source.Tariff,Source.ROAgent,Source.IBCName,Source.CD,Source.Batch,Source.JasbNumber,Source.SheetNo, Source.ContactName,Source.ContactNumber,Source.FOName,Source.[Address&LandMark],Source.NatureOfBusiness)" +
"when matched then update set Batch = Source.Batch, JasbNumber = Source.JasbNumber Where Target.Batch=Source.Batch;";
Replace your WHERE clause with additional WHEN MATCHED clause condition:
string mergeSql = "merge into " + tableName + " as Target " +
"using Ro_Consumers_Temp as Source " +
"on " +
"Target.ContractNo=Source.ContractNo " +
"when not matched then " +
"insert values (Source.Ronumber,Source.ContractNo,Source.BusinessPartner,Source.ContractAccount,Source.IBC,Source.Portion,Source.MRU,Source.Installation,Source.MeterNo,Source.LegacyNumber,Source.ConsumerNo,Source.ConsumerName,Source.Address,Source.Tariff,Source.ROAgent,Source.IBCName,Source.CD,Source.Batch,Source.JasbNumber,Source.SheetNo, Source.ContactName,Source.ContactNumber,Source.FOName,Source.[Address&LandMark],Source.NatureOfBusiness)" +
"when matched " +
"and Target.Batch=Source.Batch " + // <<< Move the clause here
"then update set Batch = Source.Batch, JasbNumber = Source.JasbNumber";
See MERGE statement documentation for more info.

Windows App c# SQLlite Database Query

Really new to SQL and I have spent days trying to do queries in my windows store app but can not get the where clause to work
I use the following code to query my database
string query = string.Empty;
public async Task<List<CityClass>> GetListCities(int fred)
{
List<CityClass> objLstCoty = new List<CityClass>();
try
{
query = "Select " + DBColumns.Id + "," + DBColumns.WORKNUM + "," + DBColumns.FAULTREF + " from " + DataBaseWrapper.Cities;
objLstCoty = await con.QueryAsync<CityClass>(query);
tb1.Text = "ID: " + objLstCoty[fred].Id;
tb2.Text = "Fault Ref: " + objLstCoty[fred].FAULTREF;
tb3.Text = "Work Number: " + objLstCoty[fred].WORKNUM;
}
catch (Exception ex)
{
//return null;
throw ex;
}
return objLstCoty;
}
This query 3 columns in my database and puts the data into 3 textboxs
How do I add a where statement so that it only returns the data where the WORKNUM equals a certain number eg WORKNUM = "112000"
I Thought adding + " where " + DBColumns.WORKNUM = "112000"; would work but it does not
Any Help is appreciated
Mark
Thanks for all your help guiding me in the right direction I managed to get it to work using
var ITEM = db.Query("Select * From Cities where WORKNUM='" + srcnum + "' ").FirstOrDefault();
where srcnum is the number i wanted to search for in the WORKNUM column
i can then just fill the textblocks using item.[columnname]
Mark
Looking at how you would add that WHERE clause to the end of your query, it wouldn't even compile as the = sign is outside of the string you're building up.
Try doing the following:
query = "Select " + DBColumns.Id + "," + DBColumns.WORKNUM + "," + DBColumns.FAULTREF + " from " + DataBaseWrapper.Cities + " where " + DBColumns.WORKNUM + " = 112000";

Update/Insert into table

I have to update table on SQL Server but first i have to check for existing data in table so if data is there update it, if not make a new insert:
cmd_sql.CommandText = " SELECT BrDok as id_dok " +
" FROM ordersstavke " +
" WHERE SifParFil = '" + rw_mat["sifskl_kor"] + "'" +
" AND DokumentTip = '" + rw_mat["vrst_dok"] + "'";
MySqlDataAdapter sql_adapter = new MySqlDataAdapter(cmd_sql);
DataSet dt_dok = new DataSet("DOK_MAT_EXCHANGE");
sql_adapter.Fill(dt_dok);
if (dt_dok.Tables["DOK_MAT_EXCHANGE"].Rows.Count == 0)
{
myQuery = " INSERT INTO ordersstavke (BrDok, DocumentTip, SifParFil) " +
" VALUES ('" + rw_mat["brdok"] + "', '" +
rw_mat["vrst_dok"] + "', '" +
rw_mat["sifskl_kor"] + "')";
}
else
{
UPDATE DATA
}
But I have an error in the code, the error is here if (dt_dok.Tables["DOK_MAT_EXCHANGE"].Rows.Count == 0)
Object reference not set to an instance of an object.
The problem is in this if statement...
DOK_MAT_EXCHANGE is the name of the DataSet, not of the first table.
You should test with
if (dt_dok.Tables[0].Rows.Count == 0)
Also, I think is better to use a syntax like this to discover how many records are presents
cmd_sql.CommandText = "SELECT COUNT(BrDok) as id_dok " +
" FROM ordersstavke " +
" WHERE SifParFil = ?p1 " +
" AND DokumentTip = ?p2";
cmd_sql.Parameters.AddWithValue("?p1", rw_mat["sifskl_kor"] );
cmd_sql.Parameters.AddWithValue("?p2", rw_mat["vrst_dok"] );
int rowCount = (Int32)cmd_sql.ExecuteScalar();
change
DataSet dt_dok = new DataSet("DOK_MAT_EXCHANGE");
to
DataSet dt_dok = new DataSet("ordersstavke ");
and
if (dt_dok.Tables["DOK_MAT_EXCHANGE"].Rows.Count == 0)
to
if (dt_dok.Tables["ordersstavke "].Rows.Count == 0)
Accessing the first table via the dataset name is incorrect, that's for setting the XML.
Instead use
dt_dok.Tables[0].Rows.Count;
That being said, you're better off writing this as a single SQL statement instead of a separate select && insert. This way you're not going to the DB multiple times.
var sql = #"if exists(select * from ordersstavke where SifParFil = ? and DokumentTip = ?)
then
-- do insert statement
else
-- do update
end if";
This might also be better done with a stored proc, so you don't have as much SQL code in C#. It's easier to manage multiple operations that way.
And for crying out loud, use SqlParameters, not string concatenation! That's just asking for trouble!
Ok, thanks guys, I wrote it like this
if (ds_dok.Tables[0].Rows.Count <= 0)
{
myQuery = " INSERT INTO ordersstavke (BrDok, " +
" SifParFil) " +
" VALUES ('" + rw_mat["brdok"] + "', '" +
rw_mat["sifskl_kor"] + "')";
}
else if (ds_dok.Tables[0].Rows.Count >= 1)
{
myQuery = "UPDATE ordersstavke " +
"SET BrDok = '" + rw_mat["brdok"] + "', " +
"SifParFil = '" + rw_mat["sifskl_kor"] + "', " +
"WHERE BrDok = " + ds_dok.Tables["ordersstavke"].Rows[0]["BrDok"].ToString() + "'";
}
But there is a small problem in the section update: s_dok.Tables["ordersstavke"].Rows[0]["BrDok"].ToString(), here it give me that loving error : Object reference not set to an instance of an object.
Maybe the update on MySQL goes on different way, I'm referencing on example on sql server and there update goes differently

SQL Update statement (MS ACCESS)

I executed the following statement but it only updates the price rows of all except Assasin creed (blank value). Also, the prices in the other rows in my table which are not defined below ironically was cleared (blank value). It seems to be working normally if i update 2 products though. What could be wrong?
(line breaks for display-wrapping only)
"UPDATE Products SET Price = IIf(Product = 'Crysis Wars'," +
CrysisWarsInput.Text +
", IIf(Product = 'Far Cry 2'," + FarCry2Input.Text +
", IIf(Product = 'Day of Defeat Source'," + DODSourceInput.Text +
", IIf(Product = 'GTA 4'," + GTA4Input.Text +
", IIf(Product = 'Asassins Creed'," + AssassinsCreedInput.Text + ")))))";
Maybe because you mis-spelt "Assasins Creed"?
Either set a WHERE clause, or add Price as the default value in the last IIF
"UPDATE Products SET Price = " +
" IIf(Product = 'Crysis Wars'," + CrysisWarsInput.Text +
", IIf(Product = 'Far Cry 2'," + FarCry2Input.Text +
", IIf(Product = 'Day of Defeat Source'," + DODSourceInput.Text +
", IIf(Product = 'GTA 4'," + GTA4Input.Text +
", IIf(Product = 'Assasins Creed'," + AssassinsCreedInput.Text + ", Price)))))";
the other rows in my table which are not defined below
That's what a WHERE clause is for, to restrict which records to update.
"UPDATE Products SET Price = " +
" IIf(Product = 'Crysis Wars'," + CrysisWarsInput.Text +
", IIf(Product = 'Far Cry 2'," + FarCry2Input.Text +
", IIf(Product = 'Day of Defeat Source'," + DODSourceInput.Text +
", IIf(Product = 'GTA 4'," + GTA4Input.Text +
", " + AssassinsCreedInput.Text + ")))) +
" WHERE Product in ('Crysis Wars','Far Cry 2','Day of Defeat Source'," +
" 'GTA 4','Assasins Creed')";
You can also use a SWITCH statement instead of multiple IIFs.
Re assasins creed - probably a typo. Look very carefully at the value in the cell and in your query - for example, is it assassin vs assassins?
Re the others (not in the query); you need to add a "where" clause, otherwise it applies to every row in the table; that is how SQL works... I'm guessing an IN filter would be best here. Fr example
where Product in ('some title', 'another title', ...)

How can you use parameterized statements with DB2 Text Search?

I've tried this:
select * from ourschema.mytable
where contains(mysearchablefield, #searchTerms) = 1;
Where #searchTerms was set to "search terms"
Unfortunately, it only produced an error:
ERROR [42610] [IBM][DB2/NT] SQL0418N A statement contains a use of a parameter marker that is not valid. SQLSTATE=42610
Is there a way to use parameterized queries for text search with DB2? If not, is there a document which describes the syntax in detail for manual (ugh) escaping of the search terms (quotes, etc)?
Instead of #field you need to use "?". Everything is basically the same.
Okay, here is a live code sample.
sqlStmt = "SELECT COMPLAINT_NUMBER, VIOLATION_NUMBER, COMMON_ADDRESS_KEY, " +
"DEPT_CODE, DEPT_CODE_DESC, DIVISION_CODE, DIVISION_CODE_DESC, " +
"EMPLOYEE_NAME, COMPLAINT_CODE, COMPLAINT_CODE_DESC, COMPLAINT_DATE, " +
"COMMON_ADDRESS_OWNER, RESOLUTION_CODE, 1 AS SORTORDER " +
"FROM QMFILES/NVMASTP " +
"WHERE VCLOSEDATE = 0 AND " +
"DEPT_CODE LIKE #DEPT_CODE1 AND " +
"DIVISION_CODE LIKE #DIVISION_CODE1 AND " +
"COMPLAINT_DATE BETWEEN #FROM_COMPLAINT_DATE1 AND #TO_COMPLAINT_DATE1 " +
statusQry +
"UNION " +
"SELECT COMPLAINT_NUMBER, VIOLATION_NUMBER, COMMON_ADDRESS_KEY, " +
"DEPT_CODE, DEPT_CODE_DESC, DIVISION_CODE, DIVISION_CODE_DESC, " +
"EMPLOYEE_NAME, COMPLAINT_CODE, COMPLAINT_CODE_DESC, COMPLAINT_DATE, " +
"COMMON_ADDRESS_OWNER, RESOLUTION_CODE, 2 AS SORTORDER " +
"FROM QMFILES/NVMASTP " +
"WHERE VCLOSEDATE <> 0 AND " +
"DEPT_CODE LIKE #DEPT_CODE2 AND " +
"DIVISION_CODE LIKE #DIVISION_CODE2 AND " +
"COMPLAINT_DATE BETWEEN #FROM_COMPLAINT_DATE2 AND #TO_COMPLAINT_DATE2 " +
statusQry +
"ORDER BY DEPT_CODE, DIVISION_CODE, COMPLAINT_CODE, SORTORDER";
iDB2Command cmd = new iDB2Command(sqlStmt, conn);
conn.Open();
cmd.DeriveParameters();
conn.Close();
cmd.Parameters["#DEPT_CODE1"].Value = dept;
cmd.Parameters["#DIVISION_CODE1"].Value = serviceArea;
cmd.Parameters["#DEPT_CODE2"].Value = dept;
cmd.Parameters["#DIVISION_CODE2"].Value = serviceArea;
cmd.Parameters["#FROM_COMPLAINT_DATE1"].Value = Convert.ToDecimal(fromDateString);
cmd.Parameters["#TO_COMPLAINT_DATE1"].Value = Convert.ToDecimal(toDateString);
cmd.Parameters["#FROM_COMPLAINT_DATE2"].Value = Convert.ToDecimal(fromDateString);
cmd.Parameters["#TO_COMPLAINT_DATE2"].Value = Convert.ToDecimal(toDateString);
I hope this helps you out more.

Categories

Resources