I am getting 'indexOutofRangeException occurred' error - 'FixedActual'
this is the code i am using any help would be appropriated.
SqlDataReader dataReader = null;
SqlCommand Scmd = new SqlCommand("SalesGetRecalcOrderItemCosts", this._connection);
Scmd.CommandType = System.Data.CommandType.StoredProcedure;
Scmd.Transaction = currentTransaction;
Scmd.Parameters.AddWithValue("#OrderNumber", ItemSODBOM.SONO); //SoItem.fSnoNo
Scmd.Parameters.AddWithValue("#UTCompFCostRef", sUTCompFCostRef);//utcomp.fcostref
Scmd.Parameters.AddWithValue("#UTCompFCostEst", sUTCompFCostEst);//utcomp.fcostest
Scmd.Parameters.AddWithValue("#UTCompFCostMType", sUTCompFCostMType);//utcomp.fcostmtype
Scmd.Parameters.AddWithValue("#OrderItemNumber", finumber); //SoItem.finumber
Scmd.Parameters.AddWithValue("#OrderType", "S");//Sales Order
Scmd.Parameters.AddWithValue("#UseStandardTransitCost", "0");
Scmd.Parameters.AddWithValue("#GetExtendedCosts", "0");
dataReader = Scmd.ExecuteReader();
while (dataReader.Read())
{
using (System.Data.SqlClient.SqlCommand updateCommand = this._connection.CreateCommand())
{
string sql = #"
UPDATE SOITEM SET
FFIXACT = #FixedActual, FLABACT = #LaborActual, FMATLACT = #MaterialActual,
FOTHRACT = #OtherActual, FOVHDACT= #OverheadActual, FRTGSETUPA= #SetupActual,
FSUBACT = #SubcontractActual, FTOOLACT = #ToolActual,FSTANDPART = 0,
FTOTPTIME = #TotalPTime, FTOTSTIME = #TotalSTime, FULABCOST1 = #ULaborCost1
WHERE FSONO = #FSONO and FINUMBER = #FINUM
";
updateCommand.CommandText = sql;
updateCommand.CommandType = System.Data.CommandType.Text;
updateCommand.Transaction = currentTransaction;
updateCommand.Parameters.AddWithValue("#FixedActual", dataReader["FixedActual"]); //This is where i am getting error
updateCommand.Parameters.AddWithValue("#LaborActual", dataReader["LaborActual"]);
updateCommand.Parameters.AddWithValue("#MaterialActual", dataReader["MaterialActual"]);
updateCommand.Parameters.AddWithValue("#OtherActual", dataReader["OtherActual"]);
updateCommand.Parameters.AddWithValue("#OverheadActual", dataReader["OverheadActual"]);
updateCommand.Parameters.AddWithValue("#SetupActual", dataReader["SetupActual"]);
updateCommand.Parameters.AddWithValue("#SubcontractActual", dataReader["SubcontractActual"]);
updateCommand.Parameters.AddWithValue("#ToolActual", dataReader["ToolActual"]);
updateCommand.Parameters.AddWithValue("#TotalPTime", dataReader["TotalPTime"]);
updateCommand.Parameters.AddWithValue("#TotalSTime", dataReader["TotalSTime"]);
updateCommand.Parameters.AddWithValue("#ULaborCost1", dataReader["ULaborCost1"]);
updateCommand.Parameters.AddWithValue("#FSONO", ItemSODBOM.SONO);
updateCommand.Parameters.AddWithValue("#FINUM", finumber);
updateCommand.ExecuteNonQuery();
}
}
Well, the exception means your SqlDataReader doesn't have a FixedActual column. That's all we can really tell from what you've shown, to be honest. We don't know what your SalesGetRecalcOrderItemCosts stored procedure does, but it appears not to be returning exactly what you expect.
You might want to look at the SqlDataReader in a debugger and see what fields are available.
(As an aside, you should be using using statements for these resources - the command, reader etc - so that you dispose of everything properly. It's also not clear why you're using fully-qualified type names in some places but not others.)
Related
I wrote up this function to return a dataset, I was expecting a smaller dataset as there's only one value I was expecting back, but I get a rather bloated object back which I cannot find the value I am looking for, this is causing problems as I intend to use this function heavily.
I was hoping someone could spot what I am doing wrong, I have included the code, a screenshot of the returned object and what I am expecting. Any help would be greatly appreciated.
If I have not phrased anything in this question correctly feel free to let me know, I struggle to express my thoughts well.
public DataSet getPartnerParameter(string parameter)
{
using (var dbConnection = new SqlConnection(UnityHelper.IocContainer.Resolve<IConfigHelperService>().GetConnectionString("CASConnectionString")))
{
dbConnection.Open();
using (var dbCommand = new SqlCommand("GETPARTNERPARAMETER"))
{
dbCommand.CommandType = CommandType.StoredProcedure;
dbCommand.Connection = dbConnection;
SqlParameter lstrParameter = new SqlParameter("#Parameter", SqlDbType.VarChar);
lstrParameter.Value = parameter;
dbCommand.Parameters.Add(lstrParameter);
var ldaDPS = new SqlDataAdapter(dbCommand);
var ldstParameterValues = new DataSet();
ldaDPS.Fill(ldstParameterValues);
return ldstParameterValues;
}
}
}
This is what I am expecting to find
edit//
changed my code slightly but still not working.
public String[] getPartnerParameter(string parameter)
{
using (var dbConnection = new SqlConnection(UnityHelper.IocContainer.Resolve<IConfigHelperService>().GetConnectionString("CASConnectionString")))
{
dbConnection.Open();
SqlCommand dbCommand = new SqlCommand("GETPARTNERPARAMETER", dbConnection);
dbCommand.CommandType = CommandType.StoredProcedure;
SqlParameter lstrParameter = new SqlParameter("#Parameter", SqlDbType.VarChar);
lstrParameter.Value = parameter;
dbCommand.Parameters.Add(lstrParameter);
SqlDataReader reader = dbCommand.ExecuteReader();
string[] results = new string[2];
while (reader.Read())
{
results[0] = reader[0].ToString();
results[1] = reader[1].ToString();
}
if (results.Length < 1)
{
results[0] = "Cannot find Value";
results[1] = "S";
return results;
}
else
{
return results;
}
}
The error is this:
{"Procedure or function 'GETPARTNERPARAMETER' expects parameter '#Parameter', which was not supplied."}
The values you are looking for are probably in the dataSet.Tables[0].Rows[0] row.
However, if you are expecting one row back, a DataSet object seems like overkill. I would recommend avoiding the SqlDataAdapter/DataSet and instead use a SqlDataReader.
Untested code, but should give you the gist of how to use it:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand dbCommand = new SqlCommand("GETPARTNERPARAMETER", connection);
dbCommand.CommandType = CommandType.StoredProcedure;
SqlParameter lstrParameter = new SqlParameter("#Parameter", SqlDbType.VarChar);
lstrParameter.Value = "LexisNexisCreditConsentRequired";
dbCommand.Parameters.Add(lstrParameter);
SqlDataReader reader = dbCommand.ExecuteReader();
while (reader.Read())
{
var yourValue = reader[0];
var yourDataType = reader[1];
}
}
A DataSet is an object which can contain many tables. It doesn't have to, but it can, and so it also has a number of fields, properties, and methods to support that role.
For this query, look at ldstParameterValues.Tables[0].Rows[0]. Within that row, you can also see the columns with another level of bracket-indexing:
DataRow row = ldstParameterValues.Tables[0].Rows[0];
var column0Value row[0];
var column1Value = row[1];
However, the type for these results is object. You'll need to either cast the values or use one of the GetX() methods on the datarow to get results with a meaningful type.
New to stackoverflow and very much a c# beginner
Currently creating a form which produces a bar chart from data stored in a database. The chosen record is identified by pID (patient's ID) and tdate (Test date). These values are determined by 2 combo boxes that the user can select from, The problem I am having is that only the first and last records stored in the database are populating the barchart.
if (radioButtonTestResult.Checked)
{
foreach (var series in TestResultBarChart.Series)
{
series.Points.Clear();
}
string tdate = comboBox2.Text;
using (SqlConnection connection = new SqlConnection(#"Data Source= (LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\MMSEDB.mdf;Integrated Security=True"))
{
connection.Open();
string sql = "SELECT T_CLOCK_SCORE,T_LANGUAGE_SCORE,T_RECALL_SCORE,T_REGISTRATION_SCORE,T_ORIENTATION _SCORE,T_TIME FROM TEST_RESULTS WHERE P_ID='" + pID + "' AND T_DATE='"+ tdate +"'";
using(SqlCommand command = new SqlCommand(sql, connection))
{
command.CommandTimeout = 3600;
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
MessageBox.Show("hello4");
String clockScoreString = reader["T_CLOCK_SCORE"].ToString();
MessageBox.Show(clockScoreString);
clockScore = Int32.Parse(clockScoreString);
String langScoreString = reader["T_LANGUAGE_SCORE"].ToString();
langScore = Int32.Parse(langScoreString);
String recallScoreString = reader["T_RECALL_SCORE"].ToString();
recallScore = Int32.Parse(recallScoreString);
String regScoreString = reader["T_REGISTRATION_SCORE"].ToString();
regScore = Int32.Parse(regScoreString);
String orientScoreString = reader["T_ORIENTATION_SCORE"].ToString();
orientScore = Int32.Parse(orientScoreString);
String timeScoreString = reader["T_TIME"].ToString();
timeScore = Int32.Parse(timeScoreString);
}
reader.Close();
}
}
this.TestResultBarChart.Series["Series1"].Points.AddXY("Clock Score", clockScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Language Score", langScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Recall Score", recallScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Registration Score", regScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Orientation Score", orientScore);
}
}
Here is a pic of the data:
Test_results_table
here is a pic of the interface with the first record working:
interface
I know this has something to do with the reader but can't work out how to get to function correctly
Any help is very much appreciated
You are reading in a loop all the returned values, then exit from the loop and use just the last value to set your Points. You should move the Point settings inside the loop
....
while (reader.Read())
{
clockScore = Convert.ToInt32(reader["T_CLOCK_SCORE"]);
langScore = Convert.ToInt32(reader["T_LANGUAGE_SCORE"]);
recallScore = Convert.ToInt32(reader["T_RECALL_SCORE"]);
regScore = Convert.ToInt32(reader["T_REGISTRATION_SCORE"]);
orientScore = Convert.ToInt32(reader["T_ORIENTATION_SCORE"]);
timeScore = Convert.ToInt32(reader["T_TIME"]);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Clock Score", clockScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Language Score", langScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Recall Score", recallScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Registration Score", regScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Orientation Score", orientScore);
}
reader.Close();
Note that your query is built using string concatenation. This is a well known problem with database code. Never do it and use a parameterized query
EDIT
Looking at your comment below, I repeat the advice to use a parameterized query instead of string concatenation. Not only this avoid Sql Injection hacks but also you don't leave the job to understand the meaning of your values to the database engine
DateTime tDate = Convert.ToDateTime(comboBox2.Text);
......
string sql = #"SELECT
T_CLOCK_SCORE,T_LANGUAGE_SCORE,T_RECALL_SCORE,
T_REGISTRATION_SCORE,T_ORIENTATION_SCORE,T_TIME
FROM TEST_RESULTS
WHERE P_ID=#id AND T_DATE=#date";
using(SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#id", SqlDbType.Int).Value = pID;
command.Parameters.Add("#date", SqlDbType.Date).Value = tdate;
command.CommandTimeout = 3600;
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
....
In this example I assume that the variable pID is of type integer and the variable tDate is of type DateTime matching the type of the database fields. This doesn't leave any doubt to the database engine on your values.
Of course if the fields are of different type then you should change the SqlDbType accordingly.
this is how I select some content twice and when I get into the middle to select so like that it gives me trouble to select something on file.
The problem I have never seen before,
I think it's something with conn.open() and Conn.Close()
my code looks like this:
int prisId = Convert.ToInt32(Request.QueryString["Id"]);
cmd.Parameters.AddWithValue("#ppId", prisId);
cmd.CommandText = "SELECT priser FROM Priser WHERE Id = #ppId;";
conn.Open();
SqlDataReader readerPriser = cmd.ExecuteReader();
if (readerPriser.Read())
{
PanelerrorHandelsbetingelser.Visible = false;
string Brugerid = Session["id"].ToString();
cmd.Parameters.AddWithValue("#brugerid", Brugerid);
cmd.CommandText = "SELECT id, brugernavn, fornavn, efternavn FROM brugere WHERE Id = #brugerid;";
SqlDataReader readerBrugerid = cmd.ExecuteReader();
if (readerPriser.Read())
{
Session["id"] = readerBrugerid["id"].ToString();
Session["brugernavn"] = readerBrugerid["brugernavn"].ToString();
Session["fornavn"] = readerBrugerid["fornavn"].ToString();
Session["efternavn"] = readerBrugerid["efternavn"].ToString();
Session["adresse"] = TextBoxAdresse.Text;
Session["post"] = TextBoxPost.Text;
Session["telefon"] = TextBoxTelefon.Text;
Session["prisen"] = readerPriser["priser"].ToString();
LabelErrorBuyNow.Text = " - Yeaaa Jesper!";
}
else
{
LabelErrorBuyNow.Text = " - Der findes intet med dit brugerid!";
}
}
conn.Close();
problems come after line 9-10
The problem is such that it appears this one mistake on my part: There is already an open DataReader associated with this Command which must be closed first.
Always remember to release resources after they are used. So at the method end, you should:
cmd.Parameters.Clear();
readerPriser.Close();
conn.Close();
The exception tells you exactly what is wrong.
You have tried to run two SqlDataReaders over the same connection without either specifying MultipleActiveResultSets=True in your connection string or else first closing the first reader.
You have three options:
Use a second connection to run the second SqlDataReader.
Add "MultipleActiveResultSets=True" to your connection string.
Close the first SqlDataReader before using the second.
You need to close the readerPriser first be
readerPriser.Close();
Then affiliate the same command with next reader.
Always close the readers after using them.
There are two problems here. First of all, you are not placing all of your IDisposable objects into using blocks. Second, you are reusing the same SqlCommand for different queries. Third, your second Read call is using the wrong SqlDataReader.
Try
using (SqlConnection conn = new SqlConnection(...)){
conn.Open();
using (SqlCommand selectPriser = new SqlCommand("SELECT priser FROM Priser WHERE Id = #ppId;", conn))
{
selectPriser.Parameters.AddWithValue("#ppId", prisId);
using (SqlDataReader readerPriser = selectPriser.ExecuteReader())
{
if (readerPriser.Read())
{
// ...
using (SqlCommand selectBrugere = new SqlCommand("SELECT id, brugernavn, fornavn, efternavn FROM brugere WHERE Id = #brugerid;"){
string Brugerid = Session["id"].ToString();
selectBrugere.Parameters.AddWithValue("#brugerid", Brugerid);
using (SqlDataReader readerBrugerid = selectBrugere.ExecuteReader()){
if (readerBrugerid.Read()){
// ...
}
}
}
}
}
}
}
I'm just trying to return a list of columns and their attributes through a system stored procedure. What documentation I have seems to say the below code should work, but I get "Pervasive.Data.SqlClient.Lna.k: [LNA][Pervasive][ODBC Engine Interface]Invalid or missing argument." on the execute. This is PSQL v11, .NET 4.5.
using (PsqlConnection conn = new PsqlConnection(cs))
{
PsqlCommand locationCmd = new PsqlCommand();
PsqlParameter tableParam = new PsqlParameter();
PsqlParameter returnParam = new PsqlParameter();
returnParam.Direction = ParameterDirection.ReturnValue;
locationCmd.CommandText = "psp_columns";
locationCmd.Connection = conn;
locationCmd.CommandType = CommandType.StoredProcedure;
locationCmd.Parameters.Add(tableParam).Value = table;
locationCmd.Parameters.Add(returnParam);
conn.Open();
locationCmd.ExecuteNonQuery();
}
I would think the problem is this line:
locationCmd.Parameters.Add(tableParam).Value = table;
You should set the value before adding the parameter, not afterwards.
tableParam.Value = table;
locationCmd.Parameters.Add(tableParam);
I don't know about Psql but for MSSQL normally you also need to define the parameter name as its found in the stored procedure, or at least that's what I do.
SqlParameter param = new SqlParameter("#tableParam", value);
The psp_Columns system stored procedure is defined as call psp_columns(['database_qualifier'],'table_name', ['column_name']). I know that it says the database qualifier is optional, but I think it's required. You could try passing an empty string for the qualifier. Something like:
using (PsqlConnection conn = new PsqlConnection(cs))
{
PsqlCommand locationCmd = new PsqlCommand();
PsqlParameter dbParam = new PsqlParameter();
PsqlParameter tableParam = new PsqlParameter();
PsqlParameter returnParam = new PsqlParameter();
returnParam.Direction = ParameterDirection.ReturnValue;
locationCmd.CommandText = "psp_columns";
locationCmd.Connection = conn;
locationCmd.CommandType = CommandType.StoredProcedure;
locationCmd.Parameters.Add(dbParam).Value = ""; //might need two single quotes ('')
locationCmd.Parameters.Add(tableParam).Value = table;
locationCmd.Parameters.Add(returnParam);
conn.Open();
locationCmd.ExecuteNonQuery();
}
You should try to get the information of the table SCHEMA using the provided GetSchema method from the Psqlconnection. I have searched a bit on their support site and it seems that this method is supported although I haven't find a direct example using the Tables collection.
This is just an example adapted from a test on mine on SqlServer, I don't have Pervasive install, but you could try if the results are the same
using(PsqlConnection cn = new PsqlConnection("your connection string here"))
{
cn.Open();
string[] selection = new string[] { null, null, table };
DataTable tbl = cn.GetSchema("Columns", selection);
foreach (DataRow row in tbl.Rows)
{
Console.WriteLine(row["COLUMN_NAME"].ToString() + " " +
row["IS_NULLABLE"].ToString() + " " +
row["DATA_TYPE"].ToString()
);
}
}
i was trying to figure this out as well, but with the tables procedure. even though the database and table names are optional, you still have to provide values. for optional parameters, pass in DBNull.Value
this worked for me:
PsqlCommand cm = new PsqlCommand();
cm.CommandText = "psp_tables";
cm.CommandType = CommandType.StoredProcedure;
cm.Connection = new PsqlConnection();
cm.Connection.ConnectionString = <your connection string>;
cm.Parameters.Add(":database_qualifier", DBNull.Value);
cm.Parameters.Add(":table_name", DBNull.Value);
cm.Parameters.Add(":table_type", "User table");
In the last few days I am trying to get data from my SQL table and get it into my textbox.
The table name : "check".
The code I am using :
SqlDataReader myReader = null;
connection = new SqlConnection(System.Configuration.ConfigurationManager
.ConnectionStrings["ConnectionString"].ConnectionString);
connection.Open();
var command = new SqlCommand("SELECT * FROM [check]", connection);
myReader = command.ExecuteReader();
while (myReader.Read())
{
TextBox1.Text = myReader.ToString();
}
connection.Close();
I am getting nothing as a result. Anyone know why? Maybe I am not calling the SQL correctly?
using (var connection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT ColumnName FROM [check]";
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
TextBox1.Text = reader["ColumnName"].ToString();
}
}
Some comments:
don't use *, specify only those fields that you need
use using - less code, guaranteed disposal
I assume this is a test program, otherwise it does not make sense to reset Text to a in the loop
TextBox1.Text = myReader["fieldname"].ToString();
also I think you can change while with if because for every row from your table you'll overwrite textbox text!
Try this:
TextBox1.AppendText(myReader["columnname"].ToString());