Dashboard1 class this code checks for all rated work and adds up the sum total of rate and is used in the update query to update the user who did the work
{
// rate
if (listView1.SelectedItems.Count > 0)
{
if (comboBox1.Text == "")
{
MessageBox.Show("Warning : Select Rate value");
}
else
{
Author au = new Author();
au.rateReview(Convert.ToInt32(comboBox1.Text), Convert.ToInt32(listView1.SelectedItems[0].SubItems[0].Text));
List<int> score = new List<int>();
string sql = "select work.rate from work WHERE work.id ="+ listView1.SelectedItems[0].SubItems[0].Text+";";
SQLiteConnection conn = new SQLiteConnection("data source =DatabaseFile.db3");
SQLiteCommand cmd = new SQLiteCommand(conn);
conn.Open();
cmd.CommandText = sql;
SQLiteDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
score.Add(Convert.ToInt32(reader["rate"].ToString()));
}
conn.Close();
res = score.AsQueryable().Sum();
// MessageBox.Show(res.ToString());
au_update_assigned();
string sql1 = "Update user Set score = "+res+" where id =" + userid + ";";
Database db = new Database();
db.insert(sql1);
MessageBox.Show(sql1);
}
}
else
{
MessageBox.Show("Error : Select Work from List");
}
}
Database class
Insert function is called from the database class
public void insert(string query)
{
conn.Open();
SQLiteCommand cmd = new SQLiteCommand(conn);
cmd.CommandText = query;
cmd.ExecuteNonQuery();
} ```
The button even is from a **dashboard1 class** when the insert function is from the **database class** I am using sqlite I have checked for syntax error exception error but I just won't seem to up to update. It first queries for all user rated work then creates a sum total which is supposed to be part of the update command all fields have been filled
you need a connection opened and a commad to execute SQL instruction, try change:
Database db = new Database();
db.insert(sql1);
MessageBox.Show(sql1);
to:
conn.Open();
SQLiteCommand cmd2 = new SQLiteCommand(conn);
cmd2.CommandText="Update user Set score = "+res+" where id =" + userid + ";";
cmd2.ExecuteNonQuery ( );
conn.Close();
or pass connection to insert function:
public void insert(string query, SQLiteConnection _conn )
{
_conn.Open();
SQLiteCommand cmd = new SQLiteCommand(_conn);
cmd.CommandText = query;
cmd.ExecuteNonQuery();
_conn.Close();
}
and call:
db.insert(sql1, cnn);
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.
As part of an application that I am trying to develop is to update records according to the service type. Hence, the Status attribute is graded from 1 to 8 (In progress = 3 and Complete = 5). I made my code but it seems not working as I try to pass values and test update the current service type as the following:
IF progress then update to 4
IF Completed then update 6
class Program
{
static void Main(string[] args)
{
int Bend = 4;
int Complete = 6;
List<int> Status = new List<int>();
foreach (int i in Status)
{
if (i == 3)
{
SqlConnection con = new SqlConnection(#"Data Source=
(localdb)\Projects;Initial Catalog=FLS_DB;Integrated
Security=True;Connect Timeout=30;Encrypt=False;");
con.Open();
SqlCommand cmd = new SqlCommand("Update Calls set
Service =#Service", con);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Service", Bend);
con.Open();
int rowsAffected = cmd.ExecuteNonQuery();
con.Close();
}
else if (i == 5)
{
SqlConnection con = new SqlConnection(#"Data Source=
(localdb)\Projects;Initial Catalog=FLS_DB;Integrated
Security=True;
Connect Timeout=30;Encrypt=False;");
con.Open();
SqlCommand cmd = new SqlCommand("Update Calls set
Service =#Service", con);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Service", Complete);
con.Open();
int rowsAffected = cmd.ExecuteNonQuery();
con.Close();
}
}
}
}
Any help would be much appreciated!
Your code is missing a WHERE statement to update only the records that match the conditions i == 3 or i == 5, thus it seems that you don't need a loop.
You just sets Service column to the new values Bend and Complete for all records that contain the value 3 or 5 in the Service column
using(SqlConnection con = new SqlConnection(....))
using(SqlCommand cmd = con.CreateCommand())
{
con.Open();
// Sets to 4 all records with 3
cmd.CommandText = "Update Calls set Service=#Service WHERE Service=3"
cmd.Parameters.AddWithValue("#Service", Bend);
int rowsUpdatedToBend = cmd.ExecuteNonQuery();
// No need to recreate the command, just change the commandtext and
// the value of the parameter #service
cmd.CommandText = "Update Calls set Service=#Service WHERE Service=5"
cmd.Parameters["#Service"].Value = Complete
rowsUpdatedToComplete = cmd.ExecuteNonQuery();
MessageBox.Show("You have changed " + rowsUpdatedToBend + " rows to Bend state\r\n" +
"You have changed " + rowsUpdatedToComplete + " rows to Complete state");
}
Does your connection string correct?
You are opening the connection twice by if condition
Put a break point and check where the programm is going
Assuming the first point is correct; could you try something like this (code edited):
string commandText = "UPDATE Calls SET Service=Service + 1 WHERE Service = 3 OR Service = 5;";
string connectionString = #"Data Source=
(localdb)\Projects;Initial Catalog=FLS_DB;Integrated
Security=True;Connect Timeout=30;Encrypt=False;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
try
{
connection.Open();
int rowsAffected = command.ExecuteNonQuery();
Console.WriteLine("RowsAffected: {0}", rowsAffected);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
I am trying to display pictures from my SQLSEVER database on my website. My users have a picture field with a picture datatype. If the picture column is null, then I want the picture displayed to be a egg.jpg, but right now for every person their picture is egg.jpg, even if they have a picture in the database. Here is my method.
public string getImageUrl()
{
System.Data.SqlClient.SqlConnection sc = new System.Data.SqlClient.SqlConnection();
sc.ConnectionString = "Server =MRCOMPUTER2\\SQLEXPRESS; Database = WBL;Trusted_Connection=Yes;";
sc.Open();
System.Data.SqlClient.SqlCommand insert = new System.Data.SqlClient.SqlCommand();
insert.Connection = sc;
insert.CommandText = "SELECT profilePicture from SystemUser";
insert.ExecuteNonQuery();
SqlDataReader reader = insert.ExecuteReader();
string url = "";
while (reader.Read())
{
if ( !DBNull.Value.Equals(reader[0]))
{
url = "data:Image / png; base64," + Convert.ToBase64String((byte[])reader[0]);
}
else {
url = "images/egg.jpg";
}
}
return url;
}
Your code returns the image for the last user in your table.
Here:
insert.CommandText = "SELECT profilePicture from SystemUser";
you select all users from the table (not just the one you currently show). Then:
while (reader.Read())
{
...
url = ...
...
}
you re-assign url inside every iteration of your while loop. This is semantically equivalent to:
url = ... /* The value determined from the last record of the reader. */
Thus, all your users show the same image - the one of the last user in your table.
You SELECT statement is attached into a ExecuteNonQuery?
Take it off.
Just perform the READER statement...
Try this:
static void Main(string[] args)
{
string connectionString = "Server=.;Database=AA;Trusted_Connection=True;";
/*
CREATE TABLE [dbo].[SystemUser]
(
[ProfilePicture] [varbinary](max) NULL
)
*/
using (SqlConnection connection = new SqlConnection(connectionString))
{
string sql = #"
INSERT [AA].[dbo].[SystemUser] ([ProfilePicture]) VALUES (#ProfilePicture);
INSERT [AA].[dbo].[SystemUser] ([ProfilePicture]) VALUES (NULL);
";
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
byte[] bytes = File.ReadAllBytes(#"1.jpg");
command.Parameters.AddWithValue("#ProfilePicture", bytes);
connection.Open();
command.ExecuteNonQuery();
}
DataSet ds = new DataSet();
using (SqlConnection connection = new SqlConnection(connectionString))
{
string sql = #"
SELECT TOP 1000 [ProfilePicture] FROM [AA].[dbo].[SystemUser];
";
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
connection.Open();
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(ds);
}
var rows = ds.Tables[0].Rows.Cast<DataRow>();
foreach (DataRow row in rows)
{
byte[] bytes = row.Field<byte[]>(0);
if (bytes != null)
{
string fileName = Guid.NewGuid().ToString("N") + ".jpg";
File.WriteAllBytes(fileName, bytes);
}
}
}
Can you try using the name of the column such as
var Val = (String)reader["column name"];
Also, try something like this to test:
while (reader.Read())
{
var testVal = reader.GetString(0);
Var testVal2 = reader.GetString(1);
The database is not storing information all on the same row. On the first page, when I click the button it records it and that's fine, it's stored. Then on the next page, when i click the button, it stores the information, but on a different row? Any solutions? Heres the problem, and code below.
PAGE 1
public void addInformationToDatabase()
{
string Sex = ddlGender.Text;
string Name = tbxName.Text;
string DOB = tbxDOB.Text;
string connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection Con = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand();
command.Connection = Con;
command.CommandType = CommandType.Text;
command.CommandText = "INSERT INTO [User] (GenderID,Name,DOB) VALUES(#Sex,#Name,#DOB)";
command.Parameters.AddWithValue("#Sex", Sex);
command.Parameters.AddWithValue("#Name", Name);
command.Parameters.AddWithValue("#DOB", DOB);
try
{
Con.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
Con.Close();
}
}
2ND PAGE
public void save()
{
string checkboxSelection = CheckBoxList1.SelectedItem.ToString();
string connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection Con = new SqlConnection(connectionString);
SqlCommand c = new SqlCommand();
c.Connection = Con;
c.CommandType = CommandType.Text;
c.CommandText = "INSERT INTO [User] (Ans1) VALUES(#Ans1)";
c.Parameters.AddWithValue("#Ans1", checkboxSelection);
try
{
Con.Open();
c.ExecuteNonQuery();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
Con.Close();
}
}
Any help appreciated
your first page needs to get the ID back following the insert and then your second page needs to do an update based on that ID, not a subsequent insert.
There are a lot of resources about getting ids back - e.g How to get last inserted id?
(I'm assuming the id field uniquely identifies your row)
first query -
c.CommandText = "INSERT INTO [User] (Ans1) VALUES(#Ans1); SELECT SCOPE_IDENTITY()";
...
int userID = (Int32) c.ExecuteScalar();
you'll need to pass that ID to your 2nd page and change the insert to be an update:
"UPDATE User] SET Ans1 = #Ans1 WHERE Id = #id";
you'll also need to add the id as a parameter
c.Parameters.AddWithValue("#id", userID);