I want to update a dataset in a DB2/AS400 table.
The problem is if I there is string parameter in the parameters list the command does not find a row to update.
For example: If I run the command only with the company number the command will succeed. If I run the command with the company number and facility number the command fails.
Does anyone have any idea?
IDbConnection cn = Tools.GetCnApp();
try
{
StringBuilder sql = new StringBuilder();
sql.AppendLine("UPDATE " + Tools.GetSchemeApp() + "/ChangeReasonAssignments");
sql.AppendLine(" SET Confirmed = #CONF, Confirmed_By = #CONFBY, Confirmed_At = #CONFAT");
sql.AppendLine(" WHERE Company = #CONO AND Facility = #FACI AND Department = #DEPT");
sql.AppendLine(" AND Production_Group = #PRGR AND Manufacturing_Order = #ORDR AND Order_Operation = #OPER");
sql.AppendLine(" AND Confirmed = 0");
IDbCommand cmd = cn.CreateCommand();
cmd.SetParameter("#CONO", this.CompanyNumber);
cmd.SetParameter("#FACI", this.FacilityNumber);
cmd.SetParameter("#DEPT", this.ProductionGroup.Department.Name);
cmd.SetParameter("#PRGR", this.ProductionGroup.Name);
cmd.SetParameter("#ORDR", this.ManufacturingNumber);
cmd.SetParameter("#OPER", this.OperationNumber);
cmd.SetParameter("#CONFBY", Base.User);
cmd.SetParameter("#CONFAT", DateTime.Now.ToString());
cmd.SetParameter("#CONF", 1);
cmd.CommandText = sql.ToString();
if (cmd.ExecuteNonQuery() > 0)
{
}
EDIT
The datatypes in database are:
Company: INTEGER
Facility: VARCHAR
Dpartment: VARCHAR
Production_Group: VARCHAR
Manufacturing_Order:INTEGER
Order_Operation: INTEGER
The datatypes in .NET are:
CompanyNumber: int
FacilityNumber: String
Departmentname: String
ProductionGroup: String
Manufacturingorder: int
OrderOperation: int
sql.ToString() results:
UPDATE TSAEDBDEV/ChangeReasonAssignments SET Confirmed = #CONF, Confirmed_By = #CONFBY, Confirmed_At = #CONFAT WHERE Company = #CONO AND Facility = #FACI AND Confirmed = 0
Try to set the string values into ': cmd.SetParameter("#DEPT", "'" + this.ProductionGroup.Department.Name + "'");
Related
I am facing an sql challenge here.
i have a database with a table called stockstable, & in this table, the only column with data type INT is quantity.
Below is my code where i am trying to update values in the table but i get an sql error which says :
java.sql.SQLSyntaxErrorException: Columns of type 'INTEGER' cannot hold values of type 'CHAR'.
But clearly i am writing an int in variable quantity into my table column quantity.
The order of the table columns is exactly as is my SQL Query.
Where might i be going wrong?
public void updateItemData() throws SQLException{
try{
Integer updatedQuantity = Integer.parseInt(jTextFieldQuantity.getText());
double updatedBuyingPrice = Double.parseDouble(jTextFieldBuyingPrice.getText());
double updatedSellingPrice = Double.parseDouble(jTextFieldSellingPrice.getText());
String updatedName = jTextFieldName.getText().toUpperCase();
String updatedID = jTextFieldItemID.getText();
String updatedDescription = jTextFieldDescription.getText().toUpperCase();
java.sql.Date newReceivingDate = new java.sql.Date(jDateChooserReceivingDate.getDate().getTime());
newReceivingDate.toString();
Class.forName("org.apache.derby.jdbc.ClientDriver");
java.sql.Connection con = DriverManager.getConnection("jdbc:derby:C:\\Program Files\\ERS\\Database\\EmployeeDB", "axle","axle");
String list5 = "UPDATE STOCKSTABLE SET name = '"+updatedName+"',"
+ "description = '"+updatedDescription+"',"
+ "id = '"+updatedID+"',"
+ "quantity = '"+updatedQuantity+"',"
+ "systemdate = '"+systemDate+"',"
+ "receivingdate = '"+newReceivingDate+"',"
+ "buyingprice = '"+updatedBuyingPrice+"',"
+ "sellingprice = '"+updatedSellingPrice+"' where id = '"+jTextFieldItemID.getText()+"'";
////////////////////////*********************************createStatement
Statement stmt = con.createStatement();
JOptionPane.showMessageDialog(null, "QUANTITY :"+updatedQuantity);
stmt.executeUpdate(list5);
JOptionPane.showMessageDialog(null, "HERE");
//ResultSet rs = stmt.executeQuery(list5);
///////////////////////**********************************end of createStatement
//jTableStocks.setModel(DbUtils.resultSetToTableModel(rs));
refresh();
jButton5.setText("ADD TO STOCK");
JOptionPane.showMessageDialog(null, "Update Successful");
} catch (ClassNotFoundException ex) {
JOptionPane.showMessageDialog(null, "Update Error!");
Logger.getLogger(MainMenu.class.getName()).log(Level.SEVERE, null, ex);
}
}
We created a Windows Form to update a table in SQL Server.
First I click Enter ID to retrieve details from database, then after changing some data, when I click on Update button, I get an error:
Procedure or function 'UPDATE' expects parameter '#Id', which was not supplied.
Windows Form Design :
Click here
Error :
Click here
Code for Windows Form:
public partial class Update : Form
{
string connectionString = #"Data Source=AMAR;Initial Catalog=Hotel;Integrated Security=True";
public Update()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
{
TestObject t = null;
string spName = "Get";
//string queryText = "Select * from TestTable where Id = " +txtId.Text;
SqlConnection conn = new SqlConnection(connectionString);
//SqlCommand com = new SqlCommand(spName, conn);
SqlCommand com = new SqlCommand(spName, conn);
com.Parameters.AddWithValue("#Id", ID.Text);
com.CommandType = CommandType.StoredProcedure;
conn.Open();
using (SqlDataReader reader = com.ExecuteReader())
{
t = new TestObject();
while (reader.Read())
{
t.Id = reader["ID"].ToString();
t.Status = reader["Status"].ToString();
t.FName = reader["FirstName"].ToString();
t.LName = reader["LastName"].ToString();
t.Addr = reader["Address"].ToString();
t.City = reader["City"].ToString();
t.State = reader["State"].ToString();
t.Country = reader["Country"].ToString();
t.PhoneNo = reader["PhoneNo"].ToString();
t.Email = reader["EmailId"].ToString();
t.Pin = reader["Pincode"].ToString();
t.CheckIn = reader["CheckIn"].ToString();
t.CheckOut = reader["CheckOut"].ToString();
t.AdultNo = reader["AdultNo"].ToString();
t.ChildNo = reader["InfantNo"].ToString();
t.InfantNo = reader["InfantNo"].ToString();
t.RoomNo = reader["RoomNo"].ToString();
};
}
Statustxt.Text = t.Status;
txtfName.Text = t.FName;
txtlName.Text = t.LName;
txtAddr.Text = t.Addr;
City.Text = t.City;
State.Text = t.State;
Country.Text = t.Country;
PhoneNo.Text = t.PhoneNo;
EmailID.Text = t.Email;
Pincode.Text = t.Pin;
CheckIN.Text = t.CheckIn;
CheckOut.Text = t.CheckOut;
Adult.Text = t.AdultNo;
Child.Text = t.ChildNo;
Infant.Text = t.InfantNo;
RoomNo.Text = t.RoomNo;
}
}
private void btnUpdate_Click(object sender, EventArgs e)
{
string Stat = Statustxt.Text;
string FirstName = txtfName.Text;
string LastName = txtlName.Text;
string Address=txtAddr.Text;
string Cities=City.Text;
string States= State.Text;
string Countries =Country.Text;
string PhoneNos= PhoneNo.Text;;
string EmailId= EmailID.Text;
string PinCode=Pincode.Text;
string CIn=CheckIN.Text;
string COut=CheckOut.Text;
string AdultNo=Adult.Text;
string ChildNo=Child.Text;
string InfantNo=Infant.Text;
string RoomNos=RoomNo.Text;
TestObject obj = new TestObject();
obj.Stat=Statustxt.Text;
obj.FirstName = txtfName.Text;
obj.LastName = txtlName.Text;
obj.Address=txtAddr.Text;
obj.Cities=City.Text;
obj.States= State.Text;
obj.Countries =Country.Text;
obj.PhoneNos= PhoneNo.Text;;
obj.EmailId= EmailID.Text;
obj.PinCode=Pincode.Text;
obj.CIn=CheckIN.Text;
obj.COut=CheckOut.Text;
obj.AdultNo=Adult.Text;
obj.ChildNo=Child.Text;
obj.InfantNo=Infant.Text;
obj.RoomNos=RoomNo.Text;
string spName = "UPDATE";
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand com = new SqlCommand(spName, conn);
conn.Open();
com.Parameters.AddWithValue("#Stat", obj.Stat);
com.Parameters.AddWithValue("#FirstName", obj.FirstName);
com.Parameters.AddWithValue("#LastName", obj.LastName);
com.Parameters.AddWithValue("#Address", obj.Address);
com.Parameters.AddWithValue("#Cities", obj.Cities);
com.Parameters.AddWithValue("#States", obj.States);
com.Parameters.AddWithValue("#Countries", obj.Countries);
com.Parameters.AddWithValue("#PhoneNos", obj.PhoneNos);
com.Parameters.AddWithValue("#EmailId", obj.EmailId);
com.Parameters.AddWithValue("#PinCode", obj.PinCode);
com.Parameters.AddWithValue("#CIn", obj.CIn);
com.Parameters.AddWithValue("#COut", obj.COut);
com.Parameters.AddWithValue("#AdultNo", obj.AdultNo);
com.Parameters.AddWithValue("#ChildNo", obj.ChildNo);
com.Parameters.AddWithValue("#InfantNo", obj.InfantNo);
com.Parameters.AddWithValue("#RoomNos", obj.RoomNos);
com.CommandType = CommandType.StoredProcedure;
com.ExecuteNonQuery();
conn.Close();
MessageBox.Show("Customer Details updated in system");
}
}
SQL Server stored procedure:
ALTER PROCEDURE [dbo].[UPDATE]
#Id int,
#Stat nvarchar(100),
#FirstName nvarchar(100),
#LastName nvarchar(100),
#Address nvarchar(100),
#Cities nvarchar(100),
#States nvarchar(100),
#Countries nvarchar(100),
#PhoneNos int,
#EmailId nvarchar(100),
#PinCode int,
#CIn nvarchar(100),
#COut nvarchar(100),
#AdultNo int,
#ChildNo int,
#InfantNo int,
#RoomNos int
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
UPDATE [Hotel].[dbo].[Details] SET
[Status] = #Stat,
[FirstName] = #FirstName,
[LastName] = #LastName,
[Address] = #Address,
[City] = #Cities,
[State] =#States ,
[Country] = #Countries,
[PhoneNo] = #PhoneNos,
[EmailId] = #EmailId,
[Pincode] = #PinCode,
[CheckIn] = #CIn,
[CheckOut] = #COut,
[AdultNo] = #AdultNo,
[ChildNo] = #ChildNo,
[InfantNo] = #InfantNo,
[RoomNo] = #RoomNos
WHERE ID = #Id
END
a. as Mitch Wheat wrote in the comments, NEVER use keywords as procedures names.
b. as marc_s wrote in his comment - stop using .AddWithValue(). read the article he links to.
c. you never provide the #id parameter to the command , this is why you get the error.
d. this has nothing to do with winforms.
e. in the future, Please provide only the relevant code. if the problem is in the update button click, we don't need to see the entire form class, only the button click event handler.
I can use GetSchemaTable and GetXMLSchema to get information about field types, sizes etc. from a Foxpro DBF opened with VFPOLEDB but can not get any information pertaining to what indexes are in the tables/CDX.
I dont want to use the indexes, just the criteria on which the index is built to aid me in generating the SQL commands to create the tables on a SQL server and import the data.
I could do a DISPLAY STRUCTURE output to a text file on all of the tables and parse it in VB.NET but I am hoping there is something I am overlooking as I am not that familiar with VB.NET/OLEDB syntax yet.
Little bit of research given away these results. I have started with having a look at ForeignKey.FKTableSchema Property and unfortunately not a .NET property. Later on things looked good when I found OleDbSchemaGuid.Indexes Field and everything looked good until I ran the application and got the Method is not supported by this provider. Eventually the following article lit up the way,
GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Indexes - How to access included columns on index
and this finding
The OleDb and Odbc providers do not provide a built-in catalog method
that will return non-key ("Included") index columns.
However it was some really interesting suggestion which let to writing this little Console application for you to harvest the indexes available in the table. This is achieved by directly querying the schema table from SQL. The following example is on Employees table of famous Northwind sample database. Here you go,
//Open a connection to the SQL Server Northwind database.
var connectionString =
"Provider=SQLOLEDB;Data Source=SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=SSPI;Encrypt=False;TrustServerCertificate=False";
using (var connection = new OleDbConnection(connectionString))
{
connection.Open();
var select = "SELECT " +
" T.name AS TABLE_NAME" +
" , IX.name AS INDEX_NAME" +
" , IC.index_column_id AS IX_COL_ID" +
" , C.name AS COLUMN_NAME" +
" , IC.is_included_column AS INCLUDED_NONKEY" +
" " +
"FROM " +
" sys.tables T " +
" INNER JOIN sys.indexes IX" +
" ON T.object_id = IX.object_id " +
" INNER JOIN sys.index_columns IC" +
" ON IX.object_id = IC.object_id " +
" AND IX.index_id = IC.index_id " +
" INNER JOIN sys.columns C" +
" ON IC.object_id = C.object_id " +
" AND IC.column_id = C.column_id " +
" " +
"WHERE T.name = 'Employees'" +
"ORDER BY IC.index_column_id";
OleDbCommand cmd = new OleDbCommand(#select, connection);
cmd.CommandType = CommandType.Text;
var outputTable = new DataSet("Table");
var my = new OleDbDataAdapter(cmd).Fill(outputTable);
foreach (DataTable table in outputTable.Tables)
{
foreach (DataRow myField in table.Rows)
{
//For each property of the field...
foreach (DataColumn myProperty in table.Columns)
{
//Display the field name and value.
Console.WriteLine(myProperty.ColumnName + " = " +
myField[myProperty].ToString());
}
Console.WriteLine();
}
}
}
Console.ReadLine();
and finally the results,
TABLE_NAME = Employees
INDEX_NAME = PK_Employees
IX_COL_ID = 1
COLUMN_NAME = EmployeeID
INCLUDED_NONKEY = False
TABLE_NAME = Employees
INDEX_NAME = LastName
IX_COL_ID = 1
COLUMN_NAME = LastName
INCLUDED_NONKEY = False
TABLE_NAME = Employees
INDEX_NAME = PostalCode
IX_COL_ID = 1
COLUMN_NAME = PostalCode
INCLUDED_NONKEY = False
However, later on by removing the restrictions I managed to get over the Method is not supported by this provider. error and ended up summing it up like this shorter solution,
//Open a connection to the SQL Server Northwind database.
var connectionString =
"Provider=SQLOLEDB;Data Source=SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=SSPI;Encrypt=False;TrustServerCertificate=False";
using (OleDbConnection cnn = new OleDbConnection(connectionString))
{
cnn.Open();
DataTable schemaIndexess = cnn.GetSchema("Indexes",
new string[] {null, null, null});
DataTable schemaIndexes = cnn.GetOleDbSchemaTable(
OleDbSchemaGuid.Indexes,
new object[] {null, null, null});
foreach (DataRow myField in schemaIndexes.Rows)
{
//For each property of the field...
foreach (DataColumn myProperty in schemaIndexes.Columns)
{
//Display the field name and value.
Console.WriteLine(myProperty.ColumnName + " = " +
myField[myProperty].ToString());
}
Console.WriteLine();
}
Console.ReadLine();
}
Which results to a longer output to sort out but part of it would be
TABLE_CATALOG = Northwind
TABLE_SCHEMA = dbo
TABLE_NAME = Employees
INDEX_CATALOG = Northwind
INDEX_SCHEMA = dbo
INDEX_NAME = LastName
PRIMARY_KEY = False
UNIQUE = False
CLUSTERED = False
TYPE = 1
FILL_FACTOR = 0
INITIAL_SIZE =
NULLS =
SORT_BOOKMARKS = False
AUTO_UPDATE = True
NULL_COLLATION = 4
ORDINAL_POSITION = 1
COLUMN_NAME = LastName
COLUMN_GUID =
COLUMN_PROPID =
COLLATION = 1
CARDINALITY =
PAGES = 1
FILTER_CONDITION =
INTEGRATED = False
Perfect!
Everything I needed to extract. Since it was in vb.net section I posted my rough code, I filtered the fields returned so I could list a few here.
It returns all pertinent information relating to the indexes, even complex ones created with expressions.
All tables in the path provided in the Connection String with CDX indexes will be returned.
TABLE_NAME = schematest
INDEX_NAME = char3ascen
NULLS = 1
EXPRESSION = char3ascen
TABLE_NAME = schematest
INDEX_NAME = expressn
NULLS = 2
EXPRESSION = LEFT(char1null,4)+SUBSTR(char2,4,2)
TABLE_NAME = schematest
INDEX_NAME = multifld
NULLS = 2
EXPRESSION = char1null+char2
TABLE_NAME = customer
INDEX_NAME = zip
NULLS = 1
EXPRESSION = zip
Private Sub GetIndexInfo_Click(sender As Object, e As EventArgs) Handles GetIndexInfo.Click
Dim cnnOLEDB As New OleDbConnection
Dim SchemaTable As DataTable
Dim myField As DataRow
Dim myProperty As DataColumn
Dim ColumnNames As New List(Of String)
Dim strConnectionString = "Provider=vfpoledb;Data Source=D:\ACW\;Collating Sequence=general;DELETED=False"
cnnOLEDB.ConnectionString = strConnectionString
cnnOLEDB.Open()
ColumnNames.Add("TABLE_NAME")
columnnames.Add("INDEX_NAME")
columnnames.Add("NULLS")
columnnames.Add("TYPE")
columnnames.Add("EXPRESSION")
SchemaTable = cnnOLEDB.GetSchema("Indexes")
'For Each myProperty In SchemaTable.Columns
For Each myField In SchemaTable.Rows
For Each myProperty In SchemaTable.Columns
If ColumnNames.Contains(myProperty.ColumnName) Then
Console.WriteLine(myProperty.ColumnName & " = " & myField(myProperty).ToString)
End If
Next
Console.WriteLine()
Next
Console.ReadLine()
DGVSchema.DataSource = SchemaTable
End Sub
I try to prevent SQL injection in SQL query. I used following code to do it but unfortunately I faced some problem. The query is not running in oracle DB:
strQuery = #"SELECT PASSWORD FROM IBK_USERS where upper(user_id) =upper(:UserPrefix) AND user_suffix=:UserSufix AND STATUS_CODE='1'";
//strQuery = #"SELECT PASSWORD FROM IBK_CO_USERS where user_id = '" + UserPrefix + "' AND user_suffix='" + UserSufix + "' AND STATUS_CODE='1'";
try
{
ocommand = new OracleCommand();
if (db.GetConnection().State == ConnectionState.Open)
{
ocommand.CommandText = strQuery;
ocommand.Connection = db.GetConnection();
ocommand.Parameters.Add(":UserSufix", OracleDbType.Varchar2,ParameterDirection.Input);
ocommand.Parameters[":UserSufix"].Value = UserSufix;
ocommand.Parameters.Add(":UserPrefix", OracleDbType.Varchar2,ParameterDirection.Input);
ocommand.Parameters[":UserPrefix"].Value = UserPrefix.ToUpper();
odatareader = ocommand.ExecuteReader();
odatareader.Read();
if (odatareader.HasRows)
{
Your parameters shouldn't contain the semicolon :. This is just an indicator in your query that the variable that follows is a parameter, but you don't have to supply that on the .NET side:
ocommand.Parameters["UserSufix"] = ...
I'm getting a syntax error in this SQL, and can't seem to figure out why?
The SQL UPDATE returns this on the error:
UPDATE Tankstationer
SET Long='12.5308724', Lat='55.6788735'
WHERE Id = 2;
Here's my code:
foreach (var row in reader)
{
var id = reader.GetInt32(0);
var adress = reader.GetString(1);
var zip = reader.GetDouble(2);
var city = reader.GetString(3);
var adressToParse = adress + " " + zip + " " + city;
GMapGeocoder.Containers.Results result = Util.Geocode(adressToParse, key);
foreach (GMapGeocoder.Containers.USAddress USAdress in result.Addresses )
{
var google_long = convertNumberToDottedGoogleMapsValid(USAdress.Coordinates.Longitude);
var google_lat = convertNumberToDottedGoogleMapsValid(USAdress.Coordinates.Latitude);
Message.Text = "Lattitude: " + google_long + System.Environment.NewLine;
Message.Text = "Longitude: " + google_lat + System.Environment.NewLine;
string updatesql = "UPDATE Tankstationer SET Long='" +google_long+ "', Lat='" +google_lat+ "' WHERE Id = " +id+"";
OleDbCommand update = new OleDbCommand();
update.CommandText = updatesql;
update.Connection = conn;
reader = update.ExecuteReader();
Message.Text = "Done";
}
}
The error is probably because you are executing a reader, but your query does not return anything. Call update.ExecuteNonQuery() instead.
"Long" is a reserved word in Access. If you can't change the schema to call that column something else, put it in brackets:
UPDATE Tankstationer
SET [Long]='12.5308724', Lat='55.6788735'
WHERE Id = 2;
try using update.ExecuteNonQuery() instead of reader.
Saw other comments too late.
I don't use access often, but mine it's using <"> for text delimiter, not <'>
Try:
"id" is being set to Int32 (var id = reader.GetInt32(0);) but you are concatenating it to a string (WHERE Id = " +id+"";). Make sure that id is cast as a string value and not an int.