Save list of Arabic strings in database - sql-server

I have a c# program. I have list of string. The elements of that list in Arabic. When I try to save the elements of list in database I see symbols "??????"
Here my code
List<string> _names = new List<string>()
{
"ذهب",
"قال",
"تعال",
"متى",
"البرمجة",
"احمد"
};
SqlConnection connection = new SqlConnection("Server=DESKTOP-JRS3DQ4; DataBase=Library_DB; Integrated Security=true");
connection.Open();
for (int index = 0; index < _names.Count; index++)
{
SqlCommand command = new SqlCommand("INSERT INTO tbl_names (id,name) VALUES ('" + index + "', '" + _names[index] + "')", connection);
command.ExecuteNonQuery();
}
connection.Close();
How I can solve this problem please?

Most likely, your problem is coming from inserting strings (as varchar) instead of NVarchar.
Your code will work more-reliably, safer & faster if you define a parameterized query and parameters before you run your loop:
List<string> _names = new List<string>()
{
"ذهب",
"قال",
"تعال",
"متى",
"البرمجة",
"احمد"
};
SqlConnection connection = new SqlConnection("Server=DESKTOP-JRS3DQ4; DataBase=Library_DB; Integrated Security=true");
connection.Open();
SqlCommand command = new SqlCommand("INSERT INTO tbl_names (id,name) VALUES (#Id, #Name)", connection);
command.Parameters.Add("#Id", SqlDbType.Int);
command.Parameters.Add("#Name", SqlDbType.NVarChar, 20); //size and type must match your DB
for (int index = 0; index < _names.Count; index++)
{
command.Parameters["#Id"].Value = index;
command.Parameters["#Name"].Value = _names[index];
command.ExecuteNonQuery();
}
connection.Close();
One last note: This will not help unless your DB has the Name column defined as a NVarChar.

Related

No value given for one or more required parameters.What is error in query

if (conn.State == ConnectionState.Closed) { conn.Open(); }
string sql = "SELECT debit.tblgltransactions AS Debit,credit.tblgltransactions AS Credit,glaccounttype.tblglaccounttypes from tblgltransactions,tblglaccounttypes where glaccounttype.tblglaccounttypes='" + cmbGeneralLedgerAccounts + "'and transactiondate.tblgltransactions='"+dtpFromDate+"'AND '"+dtpToDate+"'";
OleDbCommand cmd = new OleDbCommand(sql, conn);
OleDbDataAdapter oda = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
oda.Fill(dt);
dgvGeneralLedger.DataSource = dt.DefaultView;
if (conn.State == ConnectionState.Open) { conn.Close(); }
Maybe you missed a space in front of those "AND" statements?
And as far as I can see you are referring to transactiondate table without declaring it in from or a join statement.
EDIT:
You dont referrence both of the tables in the where condition. Dont know how that should work.

How to retrieve values from multiple rows of the same column in SQL Server

I need to search booked patients for the given date. I don"t know what the error in my code is. But I could retrieve only 1 row from the table. Please help
string sp = textBox1.Text;
SqlConnection con1 = new SqlConnection();
con1.ConnectionString = "Data Source=SWATHI-PC\\NM;Initial Catalog=clinic;Persist Security Info=True;User ID=sa;Password=sqlpass";
con1.Open();
string query = "select Booking_dt,Name from patients1 WHERE Booking_dt=#dt ";
SqlCommand cmd = new SqlCommand(query, con1);
cmd.Parameters.Add(new SqlParameter("#dt", sp));
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
listView1.Items.Add(dr[1].ToString());
}
I'd say that it's your
if (dr.Read()) { }
block only running once. I don't know the specifics of whichever language you're using, but I'm guessing you need something along the lines of
while (dr.Read())
{
listView1.Items.Add(dr[1].ToString());
}
which should iterate through dr.

Read data from SQL Server database with c#

I have list of BuilderString which I want to contain data
public List<int> IDS = new List<int>();
public List<StringBuilder> Items = new List<StringBuilder>();
What's wrong with this code?
SqlConnection con2 = new SqlConnection("Data Source=aya-PC\\SQLEXPRESS;Initial Catalog=ItemSet;Integrated Security=True");
SqlDataReader rdr2;
SqlCommand cmd2;
con2.Open();
for (int i = 0; i < IDS.Count; i++)
{
cmd2 = new SqlCommand("select item From TransactiontData where idT=#IDS[i]", con2);
cmd2.CommandType = CommandType.Text;
rdr2 = cmd2.ExecuteReader();
SqlParameter param = new SqlParameter();
param.ParameterName = "#IDS[i]"
while (rdr2.Read())
{
Items[i].Append((StringBuilder)rdr2["item"]);
}
}
You need to rearrange your code a bit:
using (SqlConnection con2 = new SqlConnection("Data Source=aya-PC\\SQLEXPRESS;Initial Catalog=ItemSet;Integrated Security=True"))
using (SqlCommand cmd2 = new SqlCommand("select item From TransactiontData where idT = #IDS", con2))
{
// add the paramter to the command
cmd2.Parameter.Add("#IDS", SqlDbType.Int);
con2.Open();
for (int i = 0; i < IDS.Count; i++)
{
// set the parameter value
cmd2.Parameter["#IDS"].Value = IDS[i];
// only *THEN* call ExecuteReader()
using (SqlDataReader rdr2 = cmd2.ExecuteReader())
{
while (rdr2.Read())
{
// **NOT SURE** what you're trying to do here.....
// First of all, you need to just call Items.Add()
// to add new items to the list - and I'm TOTALLY
// UNCLEAR what you're trying to do casting the reader
// value to a StringBuilder.......
//
// Items[i].Append((StringBuilder)rdr2["item"]);
//
// replaced with what *might* make more sense.....
Items.Add(rdr2["item"].ToString());
}
rdr.Close();
}
}
con2.Close();
}
Points to note:
I would recommend to always put your SqlConnection, SqlCommand and SqlDataReader into using() {...} blocks to ensure proper disposal
you need to add your parameter and set its value BEFORE you call .ExecuteReader()!
Since the query itself never changes - there's no point in creating a new SqlCommand on every iteration. Create the command once - and then just set the parameter value (which is the only thing changing) once per iteration
You need to assign the parameter value in the application code rather than within the query. I'm not sure exactly what you are trying to accomplish by casting the column value as a StringBuilder. Assuming that each StringBuilder item is to contain a single string retrieved from a varchar/nvarchar column, the example below will do that.
for (int i = 0; i < IDS.Count; i++)
{
var cmd2 = new SqlCommand("select item From TransactiontData where idT=#IDS", con2);
SqlParameter param = new SqlParameter("#IDS", SqlDbType.Int) { Value = IDS[i] };
var rdr2 = cmd2.ExecuteReader();
while (rdr2.Read())
{
Items.Add(new StringBuilder((string)rdr2["item"]));
}
}

Retrieve mssql primary key from query?

In C# Visual Studio Express Windows Forms:
How do I retrieve the primary key of a just executed insert query.
Here is my con+query code:
SqlConnection con = new SqlConnection(...);
SqlCommand command = con.CreateCommand();
command.CommandText = "INSERT INTO bestillinger (ha) VALUES (#ha);
command.Parameters.AddWithValue("#ha", listBox1.SelectedItem.ToString());
con.Open();
command.ExecuteNonQuery();
con.Close();
With a manual Close(), you risk leaking a connection if the code that uses it throws an exception. So please use using instead.
Assuming your PK is an identity column, the new value is most easily retrieved with scope_identity():
using (var con = new SqlConnection(...))
{
con.Open();
var command = con.CreateCommand();
command.CommandText = #"
INSERT INTO bestillinger (ha) VALUES (#ha);
select scope_identity();";
command.Parameters.AddWithValue("#ha", listBox1.SelectedItem.ToString());
var newPk = (long) command.ExecuteScalar();
}
As #Andomar said in his answer, ensure you properly close the connection.
Another way to return the value of the newly inserted identity field would be:
using (var con = new SqlConnection(...))
{
con.Open();
var command = con.CreateCommand();
command.CommandText = #"
INSERT INTO bestillinger (ha) OUTPUT inserted.[ID] VALUES (#ha);";
command.Parameters.AddWithValue("#ha", listBox1.SelectedItem.ToString());
var newPk = (long) command.ExecuteScalar();
}
[ID] would be replaced with the name of the identity field (or any field, or fields) that you want.

Stored Procedure returns a temporary table that I need to convert to a CSV file

I basically have a stored procedure that I call through a method:
Time_Tracker.BLL.ResultsManager.GetCSV(Convert.ToDateTime("2014-01-11"));
It returns 8 columns of data ranging from 25 to 150 records.
I need to be able to convert it to a CSV file to a path of the users choosing. I am able to get it into my code behind as an array ( Results[] TEST = new Results[25]; ) and have verified that the data is O.K. I see plenty of posts were they use a DataTable as a source to convert to CSV, but I am not sure how to load a DataTable from the method that calls the stored procedure. Same thing with DataGridView, not sure how to load the data into a DataGridView either.
I have also seen methods were they use SqlDataAdapter to populate a DataTable. Since I use methods to that work directly with stored procedures, I don't want to have to use SqlDataAdapter and provide the database configuration info each time.
IF someone could help me load it into a DataTable or DataGridView, I think I can figure it out from there.
Thank you in advance.
Eric
Just define a data table and use the load command to move the data from the reader to the data table.
http://msdn.microsoft.com/en-us/library/d7125bke.aspx
This is right from MSDN. I added two lines to load a data table.
-- Code from msdn
SqlConnection sqlConnection1 = new SqlConnection("Your Connection String");
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "StoredProcedureName";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
SqlDataReader reader = cmd.ExecuteReader();
-- This is my addition
DataTable dt = new DataTable();
dt.Load(reader);
sqlConnection1.Close();
I still do not understand what you are trying to do. You can create a data table, xml record set, via coding.
The code below can be used to translate an array to a DataTable. Some work is needed on your side to add your details.
http://msdn.microsoft.com/en-us/library/skef0k7a(v=vs.110).aspx
// Create sample Customers table.
DataTable table = new DataTable();
table.TableName = "Customers";
// Create two columns, ID and Name.
DataColumn idColumn = table.Columns.Add("ID", typeof(int));
table.Columns.Add("Name", typeof(string));
// Set the ID column as the primary key column.
table.PrimaryKey = new DataColumn[] { idColumn };
table.Rows.Add(new object[] { 0, "Mary" });
table.Rows.Add(new object[] { 1, "Andy" });
table.Rows.Add(new object[] { 2, "Peter" });
table.AcceptChanges();
return table;
I hope this helps. If not, I still do not get the business requirement.
I figured it out (See Below). I will mark this as solved and once again, Thank You for your help !
foreach (DataRow dr in dt.Rows)
{
for (int i = 0; i < iColCount; i++)
{
if (!Convert.IsDBNull(dr[i]))
{
if (dr[i] is DateTime)
{
if (((DateTime)dr[i]).TimeOfDay.TotalSeconds == 0) // Time Since Midnight (in Seconds)
{
sw.Write(((DateTime)dr[i]).ToString("yyyy-MM-dd"));
}
}
else
{
sw.Write(dr[i].ToString());
}
}
if (i < iColCount - 1) sw.Write(",");
}
sw.Write(sw.NewLine);
}
Here is what I ended up doing for anyone else looking for help:
protected void btnCSV_Click(object sender, EventArgs e)
{
try
{
// HATE EXPOSING THE DATABASE CONNECTION THIS WAY !!!
SqlConnection sqlConnection1 = new SqlConnection(DAL.DBUtils.SqlConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "[dbo].[usp.CSV_OUT]";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#DateBeg", Time_Tracker.Utilities.TimeCard_Start_Date());
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
SqlDataReader reader = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
sqlConnection1.Close();
ExportToCSV(dt, ConfigurationManager.AppSettings["CSVPath"].ToString(), "CSV_Hours_Data_" + Time_Tracker.Utilities.TimeCard_Start_Date().AddDays(+6).ToString("MM_dd_yyyy") + ".csv");
}
catch (Exception ex)
{
Utilities.ErrorLog(ex.Message, ex.GetType().ToString(), ex.StackTrace, #"Time_Tracker.txt");
}
}
public static void ExportToCSV(DataTable dt, string strFilePath, string fileName)
{
try
{
var sw = new StreamWriter(strFilePath + fileName, false);
// Write the headers.
int iColCount = dt.Columns.Count;
for (int i = 0; i < iColCount; i++)
{
sw.Write(dt.Columns[i]);
if (i < iColCount - 1) sw.Write(",");
}
sw.Write(sw.NewLine);
// Write rows.
foreach (DataRow dr in dt.Rows)
{
for (int i = 0; i < iColCount; i++)
{
if (!Convert.IsDBNull(dr[i]))
{
string output = dr[i].ToString();
if (dr[i] is DateTime)
{
if (((DateTime)dr[i]).TimeOfDay.TotalSeconds == 0) // Time Since Midnight (in Seconds)
{
output = (((DateTime)dr[i]).ToString("yyyy-MM-dd"));
}
}
if (output.Contains(";") || output.Contains("\""))
output = '"' + output.Replace("\"", "\"\"") + '"';
if (Regex.IsMatch(output, #"(?:\r\n|\n|\r)"))
output = string.Join(" ", Regex.Split(output, #"(?:\r\n|\n|\r)"));
sw.Write(output);
}
if (i < iColCount - 1) sw.Write(",");
}
sw.Write(sw.NewLine);
}
sw.Close();
// Causes Save As Dialog box to appear for user.
String FileName = fileName;
String FilePath = strFilePath;
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath + FileName);
response.Flush();
response.End();
}
catch (Exception ex)
{
Utilities.ErrorLog(ex.Message, ex.GetType().ToString(), ex.StackTrace, #"Time_Tracker.txt");
}
}

Resources