Oracle guid to other table - c#

At the moment I'm writing a small conversion program, it will convert the primary key strategy to the using of GUIDs in stead of integers. This is a simple client induced requirement and I can't change that.
I've added a substitute pk candidate of the RAW(16) to every table in the database and filled each record with a SYS_GUID().
I did the same for the FKs, I added a substitute column for each FK.
Now I'm in the process of linking the FKs to their PKs, by querying the parent table I get the guid/new key for the specific row, after that I want to insert into the substitute candidate FK in the child table.
Somewhat like this:
sqlString = "SELECT PK FROM " + t+ " WHERE " + fkcol+ " = " + childValue;
OracleDataReader guidReader = GetDataReader(sqlString);
while (guidReader.Read())
{
sqlString = "UPDATE T SET FK = " + guidReader["PK"];
}
Debugging this sqlString gets me the following value:
UPDATE SIS_T_USER SET FK_C_EMPLOYEE_ID
= System.Byte[]
Now, how do I go forth and save this as a nice guid in my oracle database?
EDit how:
OracleCommand command = new OracleCommand(sqlString, this.oracleConnection);
command.CommandType = CommandType.Text;
OracleParameter op1 = new OracleParameter("guid", OracleDbType.Raw);
op1.Value = guidReader["PK"];
command.Parameters.Add(op1);
try
{
command.ExecuteNonQuery();
}
catch (OracleException oex)
{
Console.WriteLine("Unable to update: {0}", oex.Message);
}

Why don't you just do this all on Oracle side?
MERGE
INTO sis_t_user s
USING employee e
ON (s.integer_fk = e.integer_pk)
WHEN MATCHED THEN
UPDATE
SET s.guid_fk = e.guid_pk

Try this code:
sqlString = "UPDATE T SET FK = '" + (new Guid((byte[])guidReader["PK"])).ToString() + "'";
Basically, you just need to create guid from bytes and then convert it to string.
There is Guid constructor that allows it: http://msdn.microsoft.com/en-us/library/90ck37x3(v=VS.100).aspx.

Related

How to check which primary key a record was assigned to in C#?

I'm using the OleDBConnectivity system to connect and use a Microsoft Access database.
I'm adding a record to the table in the database called "PayInfo", and the primary key is automatically set to the next available integer. How do I check what the value of the primary key it was assigned to is? I know this is probably an awful idea, but the only thing I could think of was to re-read the database using the entered values. The issue with this, though it's very unlikely, is that its possible to have 2 identical records stored in the database, their only difference being the primary key, and I need to be able to read the specific one.
My current subroutine for adding the record to the database is as follows:
OleDbCommand command = connection.CreateCommand();
connection.Open();
// The SQL statement:
command.CommandText = "INSERT INTO PayInfo ([UserID], [FullName], [CardType], [CardNo], [CVV], [ExpDate], [Address])" +
"VALUES ('" + Global.UserID.ToString() + "','" + PayInfo[6] + "','" + PayInfo[0] + "','" + PayInfo[1] + "','" + PayInfo[2] + "','" + exp + "','" + adress + "')";
command.Connection = connection;
command.ExecuteNonQuery(); //executes the SQL command.
connection.Close();
return true; //Successful transaction
After executing your insert query, you need to execute another query to get the generated primary key:
command.Parameters.Clear();
command.CommandText = "SELECT ##IDENTITY";
int primaryKey = Convert.ToInt32(Command.ExecuteScalar());
See Microsoft: Retrieving Identity or Autonumber Values for more details:
The Jet database engine does not support the execution of multiple
statements in a batch or the use of output parameters, so it is not
possible to use either of these techniques to return the new
Autonumber value assigned to an inserted row. However, you can add
code to the RowUpdated event handler that executes a separate SELECT
##IDENTITY statement to retrieve the new Autonumber value.

How to get the autoincremented ID inserted row using SQLiteCommand object

I have a SQLite Connection Object and a command object. I insert a row in my table using the ExecuteNonQuery function. How do I get the value of the autoincrement column (ID) from this?
Code for creating database:
creationQuery = "CREATE TABLE IF NOT EXISTS MyTable ( ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT ,MyCol1 NVARCHAR, MyCol2 NVARCHAR)";
My code for inserting values in the DB:
public void InsertIntoDB(string[] vals){
// Global connection objects (This is in an API so every time a new instance of these are created)
connObj = CreateConnection();
cmdObj = connObj.CreateCommand();
cmdObj.CommandText = "INSERT INTO MyTable ('MyCol1',MyCol2) VALUES( '" + vals[0] + "','" + vals[1] + "')";
int id = -1;
try{
cmdObj.ExecuteNonQuery();
id = (int)cmdObj.Parameters["id"].Value; // tried "#id" as well
}catch(Exception ex){
throw ex;
}
}
This code is inserting correctly. But throws an exception ( System.ArgumentOutOfRangeException) in the line where I'm trying to get the ID. Whats going on/ How do i solve this?
EDIT 1: Inside the try block, I added code to just run another query "Select max(ID) from MyTable":
try
{
cmdObj.ExecuteNonQuery();
cmdObj.CommandText = "Select Max(id) from MyTable";
SQLiteDataReader myReader = cmdObj.ExecuteReader();
while (myReader.Read())
{
id = (int)myReader["id"];
}
Console.WriteLine(id);
}
This code throws the same Exception.
select last_insert_rowid();
And you will need to execute it as a scalar query.
string sql = #"select last_insert_rowid()";
long lastId = (long)command.ExecuteScalar(sql); // Need to type-cast since `ExecuteScalar` returns an object.

UPDATE foreign key using UPDATE query

I'm trying to update a column, which is a foreign key, I'm trying to set it to a "NULL" value but the error says "ERROR 1452: Cannot add or update a child row: a foreign key constraint fails. "
try
{
con.Open();
MySqlCommand cmd = new MySqlCommand(
"UPDATE tblcdsummary
set PersonalInfoID = '" + DBNull.Value.ToString() +
"' WHERE CDID = '" + looplabel2.Text + "'", con);
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception x)
{
MessageBox.Show(x.Message);
}
Do you know what is the result of DBNull.Value.ToString()?
It is an empty string. This means that if a relationship exists between these two tables then you are trying to relate the updated record to a record on the second table based on an empty string.
Of course, if the related table has no record with its primary key set to an empty string, your update will fail.
If you want to set that field to NULL then write it explicitly (no quotes)
MySqlCommand cmd = new MySqlCommand(
#"UPDATE tblcdsummary
set PersonalInfoID = NULL
WHERE CDID = #id", con);
cmd.Parameters.Add("#id", MySqlDbType.VarChar).Value = looplabel2.Text;
Of course this works only if you allow NULL to be stored in PersonalInfoID column
PS. I have also changed your code to use a parameterized query. It is the only correct way to build sql command texts.
Don't concatenate strings. It is a really big error (Search for Sql Injection)
you need to first update value of this key in its actual table(ie. table reffered using this key)

Incorrect Syntax when creating table from textbox name

I was trying to create a table based on the name given in textbox1 .I am getting error in the following code :
Incorrect syntax near 'Ramesh'.
Here Ramesh was the value in textbox.
string Customername = Textbox1.text
SqlCommand cmd7 = new SqlCommand("CREATE TABLE '" + CustomerName + "' (ItemCode int,Quantity int,PricePerQuantity int,Brand char(50),Discount int , DateTime datetime)",connection
You don't need single quotes for your table name.
SqlCommand cmd7 = new SqlCommand("CREATE TABLE " + CustomerName + " (ItemCode int,Quantity int,PricePerQuantity int,Brand char(50),Discount int , DateTime datetime)",connection);
But weird part, don't use SqlCommand for MySQL. Use MySqlCommand and related class.
Also I would say that use parameterize queries but since you can't parameterize column name, and looks like you get it as an input, use strong validation or use whitelisting before you put it in your query.
You can read: The BobbyTables culture
remove ' from sides of the table name in query.
string Customername = Textbox1.text
SqlCommand cmd7 = new SqlCommand("CREATE TABLE " + CustomerName + " (ItemCode int,Quantity int,PricePerQuantity int,Brand char(50),Discount int , DateTime datetime)",connection
The immediate cause of the error is that you should not put table name into apostrophes. Something like this:
// put IDisposable into using
using (SqlCommand cmd7 = new SqlCommand(
// Keep SQL readable; "$" - C# 6.0 feature
$#"CREATE TABLE {Textbox1.text}(
ItemCode int,
Quantity int,
PricePerQuantity int,
Brand char(50),
Discount int,
DateTime datetime)",
connection)) {
cmd7.ExecuteNonQuery(); // execute and create the table
}

Database and DataSet are not synced regarding auto incrementing ID

I built a Database (Microsoft SqlServerCe.4.0) using Visual Studio and one table containing two fields:
id: int, primary key, not null, unique, no default value, identity
nom, we don't really care about this one
Then I built a DataSet containing this table as a DataTable and I have a DataAdapter like this :
marque_adapter = factory.CreateDataAdapter();
command = connection.CreateCommand();
command.CommandText = "SELECT * FROM " + DB_TABLE_MARQUE + ";";
marque_adapter.SelectCommand = command;
command = connection.CreateCommand();
command.CommandText = "UPDATE " + DB_TABLE_MARQUE + " SET nom = #nom WHERE id = #id;";
CreateAndAddParameterFromSource(command, "id", "id");
CreateAndAddParameterFromSource(command, "nom", "nom");
marque_adapter.UpdateCommand = command;
command = connection.CreateCommand();
command.CommandText = "DELETE " + DB_TABLE_MARQUE + " WHERE id = #id;";
CreateAndAddParameterFromSource(command, "id", "id");
marque_adapter.DeleteCommand = command;
command = connection.CreateCommand();
command.CommandText = "INSERT INTO " + DB_TABLE_MARQUE + " (nom) VALUES (#nom);";
CreateAndAddParameterFromSource(command, "nom", "nom");
marque_adapter.InsertCommand = command;
//...
data = new DataSet();
marque_adapter.Fill(data, DB_TABLE_MARQUE);
The problem arises when I try to insert a new row.
I do :
table.NewRow()
set the "nom" field
table.Rows.Add(newRow)
adapter.Update(dataSet, tableName)
If I don't do anything else, I have issues later when I try to get the ID of this row (I guess it will set it somewhere between the four instructions above).
I was expecting the DataTable to take care of generating one, but ...
So I tried remindind the DataTable to take care of the auto incrementing :
idColumn.Unique = true;
idColumn.AutoIncrement = true;
Now it works the first time, but when I run the program a second time, it starts counting from one again and I'm told that the ID should be unique. If I delete the database (the copy of the sdf file made by Visual), or if I delete the rows manually using Visual, it runs well the first time, and I get the same error after.
The problem really is when I try to save my DataSet, particularly when adding new rows (selecting, updating, deleting is fine).
Obviously I didn't get how to manage primary keys when the DataTable and the database are involved (the datatable alone is ok).
Particularly to sync the two ...
What did I miss ?
I am quite sure I have misunderstood something.
According to MSDN,
Bydefault, AcceptChanges is called implicitly after an update, and the original values in the row, which may have been AutoIncrement values assigned by ADO.NET, are lost.
So you need to create a strategy to merge the AutoIncremented value Either via ADO or getting back the incremented Id from Sql as output parameter and then merge the Identity column value as indicated in this MSDN Article.

Categories

Resources