I have this public DataTable that I am trying to run an sql query in, but the dang thing wont work...
public DataTable get_OrderTransaction_Master_ByOrderID(Int64 orderID)
{
cn = new SqlConnection(objCommon.IpcConnectionString);
cmd = new SqlCommand("select * from dbo.OrderTransaction_Master where orderID = " + orderID, cn);
cmd.CommandType = CommandType.Text;
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
I get a red line under get_OrderTransaction_Master_ByOrderID saying
Error 3 'OrderTransaction_Master.get_OrderTransaction_Master_ByOrderID(long)': not all code paths return a value C:\IPC\App_Code\OrderTransaction_Master.cs 32 22 http://localhost/ipc/
What Am I doing wrong?
The return type of your method is a DataTable, but you don't have a return statement in your method. You are also executing cmd.ExecuteNonQuery(), where you should be doing cmd.ExecuteReader() and loading a DataTable
public DataTable get_OrderTransaction_Master_ByOrderID(Int64 orderID)
{
DataTable dt = new DataTable();
using(var cn = new SqlConnection(objCommon.IpcConnectionString))
{
using(var cmd = new SqlCommand(
"select * from dbo.OrderTransaction_Master where orderID = " + orderID, cn))
{
cmd.CommandType = CommandType.Text;
cn.Open();
using(SqlDataReader reader = cmd.ExecuteReader())
{
dt.Load(reader);
return dt;
}
}
}
}
I put the SqlConnection, SqlCommand and SqlDataReader in using statements. This will properly dispose of the objects (close the connections, etc) once the using statement is exited.
your return type is a DataTable but your function doesn't return anything.
2 things, change the function to void, or return a dataTable
This method will help you no end. It is my baby, and is a real beaut.
It accepts your SQLQuery as a parameter and returns a DataTable object:
public DataTable DBGetDataTable(string SQLQuery)
{
string MethodName = "public DataTable DBGetDataTable(string SQLQuery)";
DataTable Result = null;
SqlConnection SqlConnection = null;
SqlCommand SqlCommand = null;
try
{
string DatabaseName = "";
string ServerNameOrIP = "";
string DatabaseUserID = "";
string Password = "";
string ConnectionString = "database=" + DatabaseName + ";server=" + ServerNameOrIP + ";user ID=" + DatabaseUserID + ";PWD=" + Password + ";Connection Timeout=5000";
SqlConnection = new SqlConnection(ConnectionString);
SqlCommand = new SqlCommand(SQLQuery, SqlConnection);
SqlConnection.Open();
SqlDataReader SqlDataReader = SqlCommand.ExecuteReader();
if (SqlDataReader.HasRows)
{
DataTable Dt = new DataTable();
Dt.Load(SqlDataReader);
Result = Dt;
}
}
catch (Exception ex)
{
//Common.Exception(ClassName, MethodName, ex);
}
finally
{
SqlConnection.Close();
SqlConnection.Dispose();
SqlConnection = null;
SqlCommand.Dispose();
SqlCommand = null;
}
return Result;
}
Since your database credentials will be different to mine, you will need to supply values for the following variables within the above code:
string DatabaseName = "";
string ServerNameOrIP = "";
string DatabaseUserID = "";
string Password = "";
It is very resilient and it cleans up after itself very efficiently, and as such is designed for heavy database use.
Here is an example of it being used:
StringBuilder sbSQL = new StringBuilder();
sbSQL.AppendLine(" SET DATEFORMAT DMY");
sbSQL.AppendLine(" SELECT");
sbSQL.AppendLine(" TillPayment.TillPaymentId As Id");
sbSQL.AppendLine(" , TillPayment.TransactionGuid As TransactionCode");
sbSQL.AppendLine(" , TillPayment.Amount As Price");
sbSQL.AppendLine(" , TillPayment.DiscountPercentage");
sbSQL.AppendLine(" , TillPayment.Processed As ProcessedDate");
sbSQL.AppendLine(" , PaymentType.Name As PaymentType");
sbSQL.AppendLine(" , TillPayment.ItemType As Item");
sbSQL.AppendLine(" , TillUser.LoginCode As Login");
sbSQL.AppendLine(" , TillUser.Name As UserName");
sbSQL.AppendLine(" , TillPayment.TillName As Till");
sbSQL.AppendLine(" FROM");
sbSQL.AppendLine(" [tblTillPayment] TillPayment");
sbSQL.AppendLine(" INNER JOIN [tblPaymentType] PaymentType ON TillPayment.PaymentTypeId = PaymentType.PaymentTypeId");
sbSQL.AppendLine(" INNER JOIN [tblTillUser] TillUser ON TillPayment.TillLoginCode = TillUser.LoginCode");
int SelectedMonthFrom = GetMonthAsNumber(CboMonthReportMonth.SelectedItem.Text);
int SelectedYearFrom = int.Parse(CboMonthReportYear.SelectedItem.Text);
int SelectedMonthTo = SelectedMonthFrom == 12 ? 1 : SelectedMonthFrom + 1;
int SelectedYearTo = SelectedMonthTo == 1 ? SelectedYearFrom + 1: SelectedYearFrom;
sbSQL.AppendLine(" WHERE");
sbSQL.AppendLine(" Processed >= '01-" + SelectedMonthFrom + "-" + SelectedYearFrom + " 00:00'");
sbSQL.AppendLine(" AND Processed < '01-" + SelectedMonthTo + "-" + SelectedYearTo + " 00:00'");
sbSQL.AppendLine(" AND NOT(TillUser.LoginCode = '2503' or TillUser.LoginCode = '1453')");
sbSQL.AppendLine(" ORDER BY");
sbSQL.AppendLine(" Till");
sbSQL.AppendLine(" , Processed");
DataTable DtReport = DBGetDataTable(sbSQL.ToString());
Of course, your SQL query will differ from mine.
Notice, I have used a StringBuilder object, but if you're more comfortable writing directly to a string then you may do that instead.
You wrote
I still get the same erro Error 3
'OrderTransaction_Master.get_OrderTransaction_Master_ByOrderID(long)':
not all code paths return a value
C:\IPC\App_Code\OrderTransaction_Master.cs 33 22 http:// localhost/ipc/
from before
This suggests that thereis no default return value for the method called OrderTransaction get_OrderTransaction_Master_ByOrderID(long OrderId)
I'd imagine the method in question should look something like the following:
public OrderTransaction get_OrderTransaction_Master_ByOrderID(long OrderId)
{
string MethodName = "public OrderTransaction get_OrderTransaction_Master_ByOrderID(long OrderId)";
OrderTransaction Result = null;
try{
StringBuilder sbSQL = new StringBuilder();
sbSQL.AppendLine(" SELECT");
sbSQL.AppendLine(" *");
sbSQL.AppendLine(" FROM");
sbSQL.AppendLine(" dbo.OrderTransaction_Master");
sbSQL.AppendLine(" WHERE");
sbSQL.AppendLine(" OrderID = " + OrderID);
DataTable Dt = DBGetDataTable(sbSQL.ToString())
OrderTransaction OrderTransaction = new OrderTransaction(Dt);
Result = OrderTransaction;
}
catch(Exception ex)
{
//Common.Exception(ClassName,MethodName,ex);
}
return Result;
}
Please ask if you have any questions.
Related
I have code using SqlBulkCopy to clone a lot of tables, it used to work before, but very weird, recently got exception
Received an invalid column length from the bcp client for colid
I have search this exception and still not solve my problem.
sqlBulkCopy.WriteToServer(reader) will raise this exception if a table has two continous columns which are both of type Char(1) or nvarchar(nn), and both have NULL. Sometime, changing the SqlBulkCopy.BatchSize makes it work, but many times, it will not.
After simplify, I have test case as follow, and it is reproduceable on two servers:
Create a table like below: (tested on SQL Server 2012 SP 4 and SQL Server 2016 SP2)
IF OBJECT_ID('dbo.TestTable', 'U') IS NOT NULL
DROP TABLE dbo.TestTable;
CREATE TABLE [dbo].[TestTable]
(
[value2] [char](1) NULL,
[value1] [char](1) NULL
) ON [PRIMARY]
GO
DECLARE #i int = 0
WHILE #i < 262
BEGIN
SET #i = #i + 1
INSERT INTO [dbo].[TestTable]([value2], [value1])
VALUES (null, null)
END
C# console (.net framework 4.7) code as below
class Program
{
// [change here]
static string sourceConn = #"Server={YourServer};Database={YourDatabase};User ID={userYourName};Password={yourPassword};connect timeout=15";
static void Main(string[] args)
{
CopyTable(sourceConn, sourceConn, "TestTable", "testTableBAK");
Console.ReadLine();
}
static void CopyTable(string sConnSource, string sConnDest, string sTableSource, string sTableDest)
{
if (IsTableExist(sConnDest, sTableDest))
{
RunNonQuerySQL(sConnDest, "DROP TABLE " + sTableDest);
Console.WriteLine($"existing table {sTableDest} dropped");
}
CopySchema(sConnDest, sTableSource, sTableDest);
using (SqlConnection connSource = new SqlConnection(sConnSource))
{
connSource.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connSource;
cmd.CommandText = "SELECT * FROM " + sTableSource;
// using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(sConnDest, SqlBulkCopyOptions.KeepNulls | SqlBulkCopyOptions.KeepIdentity))
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(sConnDest))
{
// sqlBulkCopy.BatchSize = 1380; // this optional setting will work if set value smaller than 1397 for testTable on my new server (SQL server 13.0.5102.14)
// sqlBulkCopy.BatchSize = 261; // this optional setting will work if set value smaller than 261 for testTable on 2 older server (SQL server 11.0.7001)
sqlBulkCopy.DestinationTableName = sTableDest;
SqlDataReader reader = cmd.ExecuteReader();
try
{
// exception here
sqlBulkCopy.WriteToServer(reader);
Console.WriteLine("table copied");
}
catch (SqlException ex)
{
Console.WriteLine(ex.Message);
}
sqlBulkCopy.Close();
}
}
}
static bool IsTableExist(string sConn, string sTableName)
{
bool result = false;
using (SqlConnection conn = new SqlConnection(sConn))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
string[] s = sTableName.Split('.');
if (s.Length > 1)
{
cmd.CommandText = "select count (*) as counter from information_schema.tables where table_name = '" + s[1] + "' and TABLE_SCHEMA='" + s[0] + "'";
}
else
{
cmd.CommandText = "select count (*) as counter from information_schema.tables where table_name = '" + sTableName + "'";
}
cmd.Connection = conn;
var count = Convert.ToInt32(cmd.ExecuteScalar());
result = count > 0;
}
return result;
}
static bool RunNonQuerySQL(string sConn, string sSQL)
{
bool result = false;
using (SqlConnection conn = new SqlConnection(sConn))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = sSQL;
cmd.Connection = conn;
var count = cmd.ExecuteNonQuery();
result = true;
}
return result;
}
static public bool CopySchema(string sConn, string sTableSource, string sTableDest)
{
return RunQuerySQL(sConn, "select * into " + sTableDest + " from " + sTableSource + " where 1=2");
}
static public bool RunQuerySQL(string sConn, string sSQL)
{
using (SqlConnection conn = new SqlConnection(sConn))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = sSQL;
cmd.Connection = conn;
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
return true;
}
else
{
return false;
}
}
}
}
I just experienced this error.
I tried to insert a string with a lenght of 5 into a table column with a definition of "varchar(4)".
The error message in my case was:
"Received an invalid column length from the bcp client for colid 2".
"Colid 2" refered to the second column of the row (DataRow) that was part of the DataTable which I used as parameter for the call to the SqlBulkCopy.WriteToServer(DataTable table) method.
The solution in my case was to add validation code that checks the lenght of the strings in my input data before trying to call SqlBulkCopy.WriteToServer().
public void addintovisitor()
{
string companyname = (txtvisitor.Text.ToUpper());
DataSet result = new DataSet();
visitorcompany vc = new visitorcompany();
string Location1 = Convert.ToString(Session["location"]);
vc.checksamecompanyname(ref result, Location1);
for (int i = 0; i < result.Tables["details"].Rows.Count; i++)
{
if (companyname == result.Tables["details"].Rows[i]["Companyname"].ToString())
{
}
else
{
string strConn = Convert.ToString(ConfigurationManager.ConnectionStrings["connectionstring"]);
SqlConnection conn = new SqlConnection(strConn);
SqlCommand cmd = new SqlCommand(
"INSERT INTO tblVisitorcompany ([CompanyName], " +
"[Location1]) " +
"VALUES(#CompanyName, #Location1)", conn);
cmd.Parameters.AddWithValue("#Companyname", companyname);
cmd.Parameters.AddWithValue("#Location1", Location1);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
}
My visitorcompany class:
public int checksamecompanyname(ref DataSet result, string Location1)
{
string strConn = Convert.ToString(
ConfigurationManager.ConnectionStrings
["connectionstring"]);
SqlConnection conn = new SqlConnection(strConn);
SqlCommand cmd = new SqlCommand
("select Companyname from tblVisitorcompany where Location1 ='" + Location1 + "'", conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
conn.Open();
da.Fill(result, "details");
conn.Close();
//Return 0 when no error occurs.
return 0;
}
I am trying to search one row at a time to check whether the sql table got the same companyname. if there is already exisiting companyname, the program will do nothing. If this is a new companyname, the program will add companyname into the sql table. However, when adding new companyname, the program will add more than once. Can someone please help me to re-edit my program such that it only add one new companyname. Many thanks.
using( var connection = new SqlConnection( "my connection string" ) ) {
using( var command = connection.CreateCommand() ) {
command.CommandText = "SELECT Column1, Column2, Column3 FROM myTable";
connection.Open();
using( var reader = command.ExecuteReader() ) {
var indexOfColumn1 = reader.GetOrdinal( "Column1" );
var indexOfColumn2 = reader.GetOrdinal( "Column2" );
var indexOfColumn3 = reader.GetOrdinal( "Column3" );
while( reader.Read() ) {
var value1 = reader.GetValue( indexOfColumn1 );
var value2 = reader.GetValue( indexOfColumn2 );
var value3 = reader.GetValue( indexOfColumn3 );
// now, do something what you want
}
}
connection.Close();
}
dont use companyname as an argument of your insert command, since it is stays the same in for loop. Use result.Tables["details"].Rows[i]["Companyname"].ToString() instead:
...
cmd.Parameters.AddWithValue("#Companyname", result.Tables["details"].Rows[i]["Companyname"].ToString());
...
Check if the value exists, then add it if not.
A simple change in your code:
bool valueFound = false;
// check if the value exists
for (int i = 0; i < result.Tables["details"].Rows.Count; i++)
{
if (companyname == result.Tables["details"].Rows[i]["Companyname"].ToString())
{
// it exists so we exit the loop
valueFound = true;
break;
}
}
// we have looped all the way without finding the value, so we can insert
if(!valueFound)
{
string strConn = Convert.ToString(ConfigurationManager.ConnectionStrings["connectionstring"]);
SqlConnection conn = new SqlConnection(strConn);
SqlCommand cmd = new SqlCommand(
"INSERT INTO tblVisitorcompany ([CompanyName], " +
"[Location1]) " +
"VALUES(#CompanyName, #Location1)", conn);
cmd.Parameters.AddWithValue("#Companyname", companyname);
cmd.Parameters.AddWithValue("#Location1", Location1);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
Off course you could check if the value exists in a more efficient way, but this should at least solve your specific problem.
I've got a c#.Net 4.5 console application and I'm trying to insert data from a DataTable to a SQL Server 2008R2 database table. I get no errors, but no data gets inserted. Here's my code:
Int32 newID = 0;
DataTable dtMaxUserID = GeneralClassLibrary.GeneralDataAccessLayer.ExecuteSelect("SELECT MAX(UserID)+1 AS NewID FROM TIUser", false, "TrackitCN");
newID = Convert.ToInt32(dtMaxUserID.Rows[0]["NewID"].ToString());
//Get new users from AllUserData
DataColumn dcRowID = new DataColumn("RowID", typeof(Int32));
//dcRowID.AllowDBNull = false;
dcRowID.AutoIncrement = true;
dcRowID.AutoIncrementSeed = 1;
dcRowID.AutoIncrementStep = 1;
//dcRowID.Unique = true;
//dcRowID.ColumnName = "RowID";
DataTable dtNewUsers = new DataTable();
dtNewUsers.Columns.Add(dcRowID);
dtNewUsers.Columns.Add("MaxID");
dtNewUsers.Columns.Add("UserID");
dtNewUsers.Columns.Add("FullName");
dtNewUsers.Columns.Add("Title");
dtNewUsers.Columns.Add("Phone");
dtNewUsers.Columns.Add("EMailAddr");
dtNewUsers.Columns.Add("Fax");
dtNewUsers.Columns.Add("Dept");
dtNewUsers.Columns.Add("Dept_Num");
dtNewUsers.Columns.Add("Location");
dtNewUsers.Columns.Add("UserDef_1");
dtNewUsers.Columns.Add("UserDef_2");
dtNewUsers.Columns.Add("Login");
dtNewUsers.Columns.Add("Password");
dtNewUsers.Columns.Add("PasswordFlags");
dtNewUsers.Columns.Add("LanguageID");
dtNewUsers.Columns.Add("NTAuthentication");
dtNewUsers.Columns.Add("NTAccount");
dtNewUsers.Columns.Add("SID");
dtNewUsers.Columns.Add("SelfServiceAccess");
dtNewUsers.Columns.Add("ImagePath");
dtNewUsers.Columns.Add("CompFlag");
dtNewUsers.Columns.Add("Employee_ID");
dtNewUsers.Columns.Add("SessionID");
string strQuery = "SELECT " + newID + " AS MaxID, LName" + ", " + "FName AS FullName, Title, Phone, EMail AS EmailAddr, Fax, Department AS Dept, Office AS Location, [Login] AS Employee_ID FROM [User] WHERE StartDate >= CAST(DATEPART(year,getdate()) AS varchar) + '-' + CAST(DATEPART(month,getdate()) AS varchar) + '-' + CAST(DATEPART(day,getdate())-1 AS varchar)";
DataTable dtTemp = GeneralClassLibrary.GeneralDataAccessLayer.ExecuteSelect(strQuery, false, "AllUserDataCN");
foreach (DataRow row in dtTemp.Rows)
dtNewUsers.ImportRow(row);
SqlTransaction tran = null;
try
{
connection.Open();
tran = connection.BeginTransaction();
//Insert new users into TIUser
SqlDataAdapter TIUser_adapter = new SqlDataAdapter();
string queryString = "SELECT * FROM TIUser WHERE 1 = 0";
TIUser_adapter.SelectCommand = new SqlCommand(queryString, connection, tran);
TIUser_adapter.Fill(dtNewUsers);
dtNewUsers.AcceptChanges();
TIUser_adapter.Update(dtNewUsers);
tran.Commit();
}
catch (System.Exception ex)
{
tran.Rollback();
throw ex;
}
finally
{
connection.Close();
}
GeneralClassLibrary is a class library we use here for a number of things; here it just executes a SELECT statement on a database. TIUser is the database table. The DataTable, dtNewUsers contains one row. I've verified that by debugging the code and inspecting the DataTable after the ImportRow is done.
After following the reply from user3787557 (THANK YOU!), I'm closer, but I'm getting a concurrency violation. I'm working on a development database, and all I'm doing is inserting a record, so I have no idea why there'd be a concurrency violation. One possibility: I alter the structure of the DataTable dtNewUsers by adding two columns. However, before I do the update, I remove those columns. The InsertCommand is fine; I've checked it in SSMS and it parses. Here's my new code:
using (SqlConnection connection = new SqlConnection(GeneralClassLibrary.GeneralConfigurationManager.ConnectionStrings["TrackitCN"].ConnectionString))
{
SqlTransaction tran = null;
connection.Open();
tran = connection.BeginTransaction();
try
{
//Create empty TIUser Data Adapter
SqlDataAdapter TIUser_adapter = new SqlDataAdapter();
SqlCommandBuilder TIUser_builder = new SqlCommandBuilder(TIUser_adapter);
string queryString = "SELECT * FROM TIUser WHERE 1 = 0";
TIUser_adapter.SelectCommand = new SqlCommand(queryString, connection, tran);
TIUser_adapter.InsertCommand = TIUser_builder.GetInsertCommand();
TIUser_adapter.UpdateCommand = TIUser_builder.GetUpdateCommand();
//Get new users from AllUserData
DataTable dtNewUsers = new DataTable();
TIUser_adapter.Fill(dtNewUsers);
DataColumn dcRowID = new DataColumn("RowID", typeof(Int32));
dcRowID.AutoIncrement = true;
dcRowID.AutoIncrementSeed = 1;
dcRowID.AutoIncrementStep = 1;
dtNewUsers.Columns.Add(dcRowID);
dtNewUsers.Columns.Add("MaxID"); string strQuery = "SELECT " + newID + " AS MaxID, LName + ', ' + FName AS FullName, Title, Phone, EMail AS EmailAddr, Fax, Department AS Dept, Office AS Location, [Login] AS Employee_ID FROM [User] WHERE StartDate >= CAST(DATEPART(year,getdate()) AS varchar) + '-' + CAST(DATEPART(month,getdate()) AS varchar) + '-' + CAST(DATEPART(day,getdate())-1 AS varchar)";
DataTable dtTemp = GeneralClassLibrary.GeneralDataAccessLayer.ExecuteSelect(strQuery, false, "AllUserDataCN");
foreach (DataRow row in dtTemp.Rows)
dtNewUsers.ImportRow(row);
//Make sure new users aren't already in Trackit
foreach (DataRow row in dtNewUsers.Rows)
{
row["UserID"] = (Convert.ToInt32(row["RowID"]) + Convert.ToInt32(row["MaxID"])).ToString();
DataTable dtOverlap = GeneralClassLibrary.GeneralDataAccessLayer.ExecuteSelect("SELECT * FROM TIUser WHERE Employee_ID = '" + row["Employee_ID"].ToString() + "'", false, "TrackitCN");
if (dtOverlap.Rows.Count > 0)
dtNewUsers.Rows.Remove(row);
}
//Remove MaxID and RowID Columns
dtNewUsers.Columns.Remove("MaxID");
dtNewUsers.Columns.Remove("RowID")
TIUser_adapter.Update(dtNewUsers);
tran.Commit();
}
catch (System.Exception ex)
{
GeneralClassLibrary.GeneralEmail.ExceptionNotification(System.Reflection.Assembly.GetExecutingAssembly().ToString(), ex.Message, ex.StackTrace);
tran.Rollback();
throw ex;
}
finally
{
connection.Close();
}
}
The Stack Trace I get is:
at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)
at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping)
at System.Data.Common.DbDataAdapter.Update(DataTable dataTable)
at UpdateTrackitUsers.Program.Main(String[] args) in c:\Users\06717\Documents\Visual Studio 2012\Projects\UpdateTrackitUsersConsole\UpdateTrackitUsersConsole\Program.cs:line 91
Line 87 is the line:
TIUser_adapter.Update(dtNewUsers);
This is the code that worked for me. Basically what you're missing on your code is to use SqlCommandBuilder to create InsertCommand and UpdateCommand. Also GET RID of AcceptChanges(). That is going to cause the new row to NOT be sent to the database. One last thing: make sure you mark the MDF database file (if you're using one) properties with "Do Not Copy" otherwise the database gets overridden every time you compile and you can't see your changes.
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.SelectCommand = new SqlCommand(queryString, connection);
adapter.InsertCommand = builder.GetInsertCommand();
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.DeleteCommand = builder.GetDeleteCommand();
DataTable dt = new DataTable();
adapter.Fill(dt);
DataRow row = dt.NewRow();
row["RegionID"] = 5;
row["RegionDescription"] = "Some region";
dt.Rows.Add(row);
//dt.AcceptChanges();
int counter = adapter.Update(dt);
}
I ran the SQL Query in SQL Server Management Studio and it worked.
I get the following error in my WinForm C# application
The parameterized query '(#word1 text)SELECT distinct [database].[dbo].[tableName].[n' expects the parameter '#word1', which was not supplied.
Here is my code
private void buttonRunQuery_Click(object sender, EventArgs e)
{
if (connection == null)
{
connection = ConnectionStateToSQLServer();
SqlCommand command = new SqlCommand(null, connection);
command = createSQLQuery(command);
GetData(command);
}
else
{
SqlCommand command = new SqlCommand(null, connection);
command = createSQLQuery(command);
GetData(command);
}
}
private SqlCommand createSQLQuery(SqlCommand command)
{
string[] allTheseWords;
if (textBoxAllTheseWords.Text.Length > 0)
{
allTheseWords = textBoxAllTheseWords.Text.Split(' ');
string SQLQuery = "SELECT distinct [database].[dbo].[customerTable].[name], [database].[dbo].[customerTable].[dos], [database].[dbo].[customerTable].[accountID], [database].[dbo].[reportTable].[customerID], [database].[dbo].[reportTable].[accountID], [database].[dbo].[reportTable].[fullreport] FROM [database].[dbo].[reportTable], [database].[dbo].[customerTable] WHERE ";
int i = 1;
foreach (string word in allTheseWords)
{
var name = "#word" + (i++).ToString();
command.Parameters.Add(name, SqlDbType.Text);
//(name, SqlDbType.Text).Value = word;
SQLQuery = SQLQuery + String.Format(" [database].[dbo].[reportTable].[fullreport] LIKE {0} AND ", name);
}
SQLQuery = SQLQuery + " [database].[dbo].[customerTable].[accountID] = [database].[dbo].[reportTable].[accountID]";
command.CommandText = SQLQuery;
}
MessageBox.Show(command.CommandText.ToString());
return command;
}
public DataTable GetData(SqlCommand cmd)
{
//SqlConnection con = new SqlConnection(connString);
//SqlCommand cmd = new SqlCommand(sqlcmdString, cn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
connection.Open();
DataTable dt = new DataTable();
da.Fill(dt);
connection.Close();
return dt;
}
The error is happening on da.Fill(dt)
Any suggestions would be helpful
Thank you
In your example, you have commented out the line where you set the value of the Parameter:
command.Parameters.Add(name, SqlDbType.Text);
//(name, SqlDbType.Text).Value = word;
If you do not set a value for a parameter, it is ignored (and won't exist).
Change to this:
command.Parameters.AddWithValue(name, word);
For clarity, consider this quote:
The value to be added. Use DBNull.Value instead of null, to indicate a null value.
From here: SqlParameterCollection.AddWithValue Method
On var name = "#word" + (i++).ToString(); use just i, increment somewhere else.
I am using the following code to insert StartDate(s) and EndDate(s) into my Iterations table. I am displaying the output in my textbox like this: dd/MM/yyyy, but am writing to my db as MM/dd/yyyy, because of the datetime data type - hence I'm using:
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-GB");
sc.Add(proj_id + "," + Convert.ToDateTime(box1.Text, ci) + "," + Convert.ToDateTime(box2.Text, ci));
I'm pretty sure this code worked just fine on localhost, but when I uploaded it to a server, I am getting the error: Insert error: the conversion of a varchar datatype to a datetime data type resulted in an out-of-range value. Please help! thanks!
Here's the full code:
private void InsertRecords(StringCollection sc)
{
SqlConnection conn = new SqlConnection(GetConnectionString());
StringBuilder sb = new StringBuilder(string.Empty);
string[] splitItems = null;
foreach (string item in sc)
{
const string sqlStatement = "INSERT INTO Iterations (ProjectID, StartDate, EndDate) VALUES";
if (item.Contains(","))
{
splitItems = item.Split(",".ToCharArray());
sb.AppendFormat("{0}('{1}','{2}','{3}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2]);
}
}
string sql = "INSERT INTO ProjectIterationMember (ProjectIterationID, MemberID) SELECT ProjectIterationID AS pro_it_id, #member_id FROM Iterations WHERE ProjectID = '" + proj_id + "'";
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sb.ToString(), conn);
SqlCommand cmd2 = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
SqlParameter memberParameter = new SqlParameter("#member_id", SqlDbType.Int);
cmd2.Parameters.Add(memberParameter);
cmd2.CommandType = CommandType.Text;
cmd2.Prepare();
memberParameter.Value = project_manager.SelectedValue;
cmd2.ExecuteNonQuery();
for (int i = 0; i < project_members.Items.Count; ++i)
{
if (project_members.Items[i].Selected)
{
memberParameter.Value = project_members.Items[i].Value;
cmd2.ExecuteNonQuery();
}
}
//Display a popup which indicates that the record was successfully inserted
Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Script", "alert('New iterations were successfully added!');", true);
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg = "Insert Error:";
msg += ex.Message;
throw new Exception(msg);
}
finally
{
conn.Close();
}
}
protected void btnSaveIterations_Click(object sender, EventArgs e)
{
int rowIndex = 0;
StringCollection sc = new StringCollection();
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("start_iteration");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("end_iteration");
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-GB");
//get the values from the TextBoxes
//then add it to the collections with a comma "," as the delimited values
sc.Add(proj_id + "," + Convert.ToDateTime(box1.Text, ci) + "," + Convert.ToDateTime(box2.Text, ci));
rowIndex++;
}
//Call the method for executing inserts
InsertRecords(sc);
Response.Redirect(Request.Url.ToString());
//r.Close();
//conn.Close();
}
}
}
First of all: concatenating together your INSERT statement is really really bad practice and opens the door to SQL Injection. Don't do it - use parametrized queries instead!
const string sqlStatement =
"INSERT INTO Iterations (ProjectID, StartDate, EndDate) " +
"VALUES(#ProjectID, #StartDate, #EndDate)";
and here:
string sql =
"INSERT INTO ProjectIterationMember (ProjectIterationID, MemberID) " +
"SELECT ProjectIterationID AS pro_it_id, #member_id " +
"FROM Iterations WHERE ProjectID = #ProjectID";
You will need to setup parameters for your SqlCommand and pass in the values before executing the query.
SqlCommand _cmd = new SqlCommand(sqlStatement, _connection);
_cmd.Parameters.Add("#ProjectID", SqlDbType.Int);
_cmd.Parameters["#ProjectID"].Value = 42;
_cmd.Parameters.Add("#StartDate", SqlDbType.DateTime);
_cmd.Parameters["#StartDate"].Value = Convert.ToDateTime(your textbox string);
_cmd.Parameters.Add("#EndDate", SqlDbType.DateTime);
_cmd.Parameters["#EndDate"].Value = Convert.ToDateTime(your textbox string);
Second: SQL Server has a range from 1/1/1753 to the end of the year 9999 - if any of your strings represent a date before 1753, you're getting this problem. Validate your inputs! When you use parametrized queries, you can do this at the point where you're setting the values of the SqlCommand.Parameters - anything outside the range that SQL Server supports (e.g. dates like "1/1/0001" and so forth) must be "sanitized" before being passed into SQL Server.