Error in Update query [Using String.Format] - sql-update

I am trying to write an update statement for inserting data from asp.net gridview to sql server 2005 database.but it is showing me an error, Please tell me how to solve.
cmdUpdate.CommandText = String.Format("Update Products SET ProductName=
{0},UnitsInStock={1},UnitsOnOrder={2},ReorderLevel={3} WHERE ProductID={4} AND
SupplierID={5}", "productname.Text, unitsinstock.Text, unitsonorder.Text,
recorderlevel.Text, employeeid.Text, supplierid.Text");
Error is-
Index (zero based) must be greater than or equal to zero and less than the size of the argument list.

Your syntax for string.Format is incorrect - each parameter after the string template should be on their own, without the double quotes surrounding them all...
This will work (notice I've removed the double quotes from just before 'productname.Text' and after 'supplierid.Text'):
String.Format("Update Products SET ProductName={0}, UnitsInStock={1}, UnitsOnOrder={2}, ReorderLevel={3} WHERE ProductID={4} AND SupplierID={5}",
productname.Text, unitsinstock.Text, unitsonorder.Text,
recorderlevel.Text, employeeid.Text, supplierid.Text);

You missed the arguments,
For instance,
str=String.Format("{0} {1}",arg1,arg2);
Do not use hard-coded sql strings. Try to learn/use parameterized queries.
EDIT:
string ConnectionString = "put_connection_string";
using (SqlConnection con = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
string sql = "Update Products SET
ProductName=#ProductName,
UnitsInStock=#UnitsInStock,
UnitsOnOrder=#UnitsOnOrder,
ReorderLevel=ReorderLevel
WHERE ProductID=ProductID AND SupplierID=#SupplierID";
cmd.CommandText = sql;
cmd.Connection = con;
cmd.Parameters.Add("#ProductName", System.Data.SqlDbType.VarChar, 50).Value =productname.Text;
cmd.Parameters.Add("#UnitsInStock", System.Data.SqlDbType.Int).Value =unitsinstock.Text;
cmd.Parameters.Add("#UnitsOnOrder", System.Data.SqlDbType.Int).Value =unitsonorder.Text;
cmd.Parameters.Add("#ReorderLevel ", System.Data.SqlDbType.Int).Value =recorderlevel.Text;
cmd.Parameters.Add("#ProductID", System.Data.SqlDbType.Int).Value =producteid.Text;
cmd.Parameters.Add("#SupplierID", System.Data.SqlDbType.Int).Value =supplierid.Text;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
EDIT: What is C# using block?
If the type implements IDisposable, it automatically disposes it
Provides a convenient syntax that ensures the correct use of IDisposable objects.
Avoiding Problems with the Using Statement

Related

How to set a NULL column value through an ADO query connected to a MySQL ODBC source in C++?

Given a given MySQL table
DESC tabl_foo;
--------------------------------
Field Type Null Key Default Extra
-----------------------------------------------------------------
fooId varchar(15) NO PRI NULL
FooDate date YES MUL NULL
I need to update FooDate for a given row. So I tried this code :
query->SQL->Add("UPDATE tbl_foo SET FooDate = :FooDate WHERE fooId = :id"):
// both arguments are AnsiString
query->Parameters->FindParam("id")->Value = FoodId;
query->Parameters->FindParam("FooDate")->Value = FooDate;
query->ExecSQL();
However, this fails
Incorrect date value: "" for folumn FooDate at row 1
It turns out that FooDate may be an empty string (or { data:NULL }), and MySQL does not like that. So, I tried setting Null() :
if (FooDate.IsEmpty())
query->Parameters->FindParam("FooDate")->Value = Null();
else
query->Parameters->FindParam("FooDate")->Value = FooDate;
But then I get this error :
Parameter object is improperly defined. Inconsistent or incomplete information was provided.
What should be the value to set for MySQL NULL?
To make the update the system needs to know the types of the parameters. It can deduce the type from the variant you apply, and MySQL can do certain conversions for you, but it's always best to specify the data type.
So what you would need is something like:
if((pParam=query->Parameters->FindParam("FooDate"))!=NULL)
{
pParam->DataType=ftDate;
if(FooDate.IsEmpty())
{
pParam->Value=Null();
}
else
{
pParam->Value=FooDate;
}
}
You may want to look at keeping FooDate as a TDateTime, but you will need to detect NULL dates properly.

SqlDataAdapter not loading datatable - C++

I have been trying to load an SQL database into a datatable in C++, however; it doesn't seem to want to work. The connection is working though, as DataReader works. Here is my code
void importDatabase() {
SqlConnection con;
SqlDataAdapter^ da;
SqlCommand cmd;
DataTable^ dt;
int count = 1;
try {
con.ConnectionString = "Data Source=MYNAME\\SQLEXPRESS;Initial Catalog=VinylRecords;Integrated Security=True";
cmd.CommandText = "SELECT * FROM Records";
cmd.Connection = %con;
con.Open();
da = gcnew SqlDataAdapter(%cmd);
dt = gcnew DataTable("Records");
Console::Write(da->ToString());
da->Fill(dt);
for (int i = 0; i < dt->Rows->Count - 1; i++) {
String^ value_string;
value_string = dt->Rows[i]->ToString();
Console::WriteLine(dt->Rows[i]->ToString());
count++;
}
cout << "There are " << count << " many records";
}
catch (Exception^ ex) {
Console::WriteLine(ex->ToString());
}
}
Please note, that I slightly altered the source name to post here, but only the first part.
What is wrong with my code?
So, the problem is here:
dt->Rows[i]->ToString()
Rows[i] is a Row object. And the Row class's ToString() method always prints out the fully qualified typename, which is what you are seeing. So this is technically working just fine. What you will need to do to get something useful is: you will need to access a specific column in that row and get it's value, then output that.
Something along the lines of:
foreach (DataRow dr in dt.Rows)
{
Console.Write(dr.Field<int>("ColumnOne"));
Console.Write(" | ");
Console.WriteLine(dr.Field<string>("ColumnTwo"));
}
I am not entirely sure on the syntax for accessing a specific cell inside of a DataTable when using C++\CLI. So I have provided the C# equivalent to explain why it is you were getting output of managed type names (e.g. "System.Data.DataRow") instead of the info inside of the Row's columns.
Also, I noticed you tagged this question with "mysql", but you are using the ADO.NET System.Data.SqlClient namespace. The SqlDataReader and SqlDataAdapter classes only work with TSQL (Microsoft's SQL Server databases) If you are actually connecting to a mysql database you will want to use the System.Data.OdbcDataAdapter class. You can read a little more here: https://msdn.microsoft.com/en-us/library/ms254931.aspx

ORA-00947: not enough values when creating object in Oracle

I created a new TYPE in Oracle in order to have parity between my table and a local c++ object (I am using OCCI interface for C++).
In the code I use
void insertRowInTable ()
{
string sqlStmt = "INSERT INTO MY_TABLE_T VALUES (:x)";
try{
stmt = con->createStatement (sqlStmt);
ObjectDefinition *o = new ObjectDefinition ();
o->setA(0);
o->setB(1);
o->setC(2);
stmt->setObject (1, o);
stmt->executeUpdate ();
cout << "Insert - Success" << endl;
delete (o);
}catch(SQLException ex)
{
//exception code
}
The code compiles, connects to db but throws the following exception
Exception thrown for insertRow Error number: 947 ORA-00947: not enough
values
Do I have a problematic "sqlStmt"? Is something wrong with the syntax or the binding?
Of course I have already setup an environment and connection
env = Environment::createEnvironment (Environment::OBJECT);
occiobjm (env);
con = env->createConnection (user, passwd, db);
How many columns are in the table? The error message indicates that you didn't provide enough values in the insert statement. If you only provide a VALUES clause, all columns in the table must be provided. Otherwise you need to list each of the columns you're providing values for:
string sqlStmt = "INSERT INTO MY_TABLE_T (x_col) VALUES (:x)";
Edit:
The VALUES clause is listing placeholder arguments. I think you need to list one for each value passed, e.g.:
string sqlStmt = "INSERT INTO MY_TABLE_T (GAME_ID, VERSION) VALUES (:x1,:x2)"
Have a look at occidml.cpp in the Oracle OCCI docs for an example.

Unable to set Reporting Services Parameters

I'm generating a reporting services report from an ASP.NET (MVC) based application but am having problems setting the parameters for the report.
I believe the issue has only occurred since we upgraded SQL Server from 2005 to 2008 R2 (and Reporting Services along with it).
The original error encountered was from calling rsExec.Render:
Procedure or function 'pCommunication_ReturnRegistrationLetterDetails'
expects parameter '#guid', which was not supplied.
Debugging the code I noticed that rsExec.SetExecutionParameters is returning the following response:
Cannot call 'NameOfApp.SQLRSExec.ReportExecutionService.SetExecutionParameters(NameOfApp.SQLRSExec.ParameterValue[],
string)' because it is a web method.
Here is the function in it's entirety:
public static bool ProduceReportToFile(string reportname, string filename, string[,] reportparams,
string fileformat)
{
bool successful = false;
SQLRS.ReportingService2005 rs = new SQLRS.ReportingService2005();
SQLRSExec.ReportExecutionService rsExec = new NameOfApp.SQLRSExec.ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rsExec.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Prepare Render arguments
string historyID = null;
string deviceInfo = null;
// Prepare format - available options are "PDF","Word","CSV","TIFF","XML","EXCEL"
string format = fileformat;
Byte[] results;
string encoding = String.Empty;
string mimeType = String.Empty;
string extension = String.Empty;
SQLRSExec.Warning[] warnings = null;
string[] streamIDs = null;
// Define variables needed for GetParameters() method
// Get the report name
string _reportName = reportname;
string _historyID = null;
bool _forRendering = false;
SQLRS.ParameterValue[] _values = null;
SQLRS.DataSourceCredentials[] _credentials = null;
SQLRS.ReportParameter[] _parameters = null;
// Get if any parameters needed.
_parameters = rs.GetReportParameters(_reportName, _historyID,
_forRendering, _values, _credentials);
// Load the selected report.
SQLRSExec.ExecutionInfo ei =
rsExec.LoadReport(_reportName, historyID);
// Prepare report parameter.
// Set the parameters for the report needed.
SQLRSExec.ParameterValue[] parameters =
new SQLRSExec.ParameterValue[1];
// Place to include the parameter.
if (_parameters.Length > 0)
{
for (int i = 0; i < _parameters.Length; i++)
{
parameters[i] = new SQLRSExec.ParameterValue();
parameters[i].Label = reportparams[i,0];
parameters[i].Name = reportparams[i, 0];
parameters[i].Value = reportparams[i, 1];
}
}
rsExec.SetExecutionParameters(parameters, "en-us");
results = rsExec.Render(format, deviceInfo,
out extension, out encoding,
out mimeType, out warnings, out streamIDs);
// Create a file stream and write the report to it
using (FileStream stream = System.IO.File.OpenWrite(filename))
{
stream.Write(results, 0, results.Length);
}
successful = true;
return successful;
}
Any ideas why I'm now unable to set parameters? The report generation works without issue if parameters aren't required.
Looks like it may have been an issue with how reporting services passes parameters through to the stored procedure providing the data. A string guid was being passed through to the report and the stored procedure expected a varchar guid. I suspect reporting services may have been noticing the string followed the guid format pattern and so passed it through as a uniqueidentifier to the stored procedure.
I changed the data source for the report from "stored procedure" to "text" and set the SQL as "EXEC pMyStoredOProcName #guid".
Please note the guid being passed in as a string to the stored procedure is probably not best practice... I was simply debugging an issue with another developers code.
Parameter _reportName cannot be null or empty. The [CLASSNAME].[METHODNAME]() reflection API could not create and return the SrsReportNameAttribute object
In this specific case it looks like an earlier full compile did not finish.
If you encounter this problem I would suggest that you first compile the class mentioned in the error message and see if this solves the problem.
go to AOT (get Ctrl+D)
in classes find CLASSNAME
3.compile it (F7)

Using Conversion Studio by To-Increase to import Notes into Microsoft Dynamics AX 2009

Currently, I'm using Conversion Studio to bring in a CSV file and store the contents in an AX table. This part is working. I have a block defined and the fields are correctly mapped.
The CSV file contains several comments columns, such as Comments-1, Comments-2, etc. There are a fixed number of these. The public comments are labeled as Comments-1...5, and the private comments are labeled as Private-Comment-1...5.
The desired result would be to bring the data into the AX table (as is currently working) and either concatenate the comment fields or store them as separate comments into the DocuRef table as internal or external notes.
Would it not require just setting up a new block in the Conversion Studio project that I already have setup? Can you point me to a resource that maybe shows a similar procedure or how to do this?
Thanks in advance!
After chasing the rabbit down the deepest of rabbit holes, I discovered that the easiest way to do this is like so:
Override the onEntityCommit method of your Document Handler (that extends AppDataDocumentHandler), like so:
AppEntityAction onEntityCommit(AppDocumentBlock documentBlock, AppBlock fromBlock, AppEntity toEntity)
{
AppEntityAction ret;
int64 recId; // Should point to the record currently being imported into CMCTRS
;
ret = super(documentBlock, fromBlock, toEntity);
recId = toEntity.getRecord().recId;
// Do whatever you need to do with the recId now
return ret;
}
Here is my method to insert the notes, in case you need that too:
private static boolean insertNote(RefTableId _tableId, int64 _docuRefId, str _note, str _name, boolean _isPublic)
{
DocuRef docuRef;
boolean insertResult = false;
;
if (_docuRefId)
{
try
{
docuRef.clear();
ttsbegin;
docuRef.RefCompanyId = curext();
docuRef.RefTableId = _tableId;
docuRef.RefRecId = _docuRefId;
docuRef.TypeId = 'Note';
docuRef.Name = _name;
docuRef.Notes = _note;
docuRef.Restriction = (_isPublic) ? DocuRestriction::External : DocuRestriction::Internal;
docuRef.insert();
ttscommit;
insertResult = true;
}
catch
{
ttsabort;
error("Could not insert " + ((_isPublic) ? "public" : "private") + " comment:\n\n\t\"" + _note + "\"");
}
}
return insertResult;
}