I have database pavadinimas.mdf, which contains two tables: Vehicle and Repairs. I want to check if both tables exist in database. So, far I managed to check if one table exist, but how to check if both exist, if not create them.
Here is my code:
string tblnm = "Vehicle";
SqlConnection conn;
using (conn = new SqlConnection(connection))
{
conn.Open();
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
cmd.CommandText = #"IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME='" + tblnm + "') SELECT 1 ELSE SELECT 0"; ;
cmd.Connection = conn;
cmd.ExecuteNonQuery();
int x = Convert.ToInt32(cmd.ExecuteScalar());
conn.Close();
if (x == 2)
{
MessageBox.Show("Lentelės yra");
}
else
{
MessageBox.Show("Lenteliu nėra.Sukuriama");
}
I also have code which should create table. Here is code:
string table1 = "Repairs";
SqlConnection conn;
conn = new SqlConnection(connection);
conn.Open();
string createString = "CREATE TABLE [dbo].['" + table1 + "'](" + "[VIN] [nvarchar](50)," + "[Taisymas] [nvarchar](50)," + "[Kaina] [decimal](18, 2))";
SqlCommand sqlCmd = new SqlCommand(createString, conn);
sqlCmd.ExecuteNonQuery();
conn.Close();
But this code don't create table in my database. Then I call this method, it is saying that table already exist, but when I check tables in database it's nothing, empty...
Are you looking for something similar to:
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='tbl1') AND EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='tbl2') SELECT 1 ELSE SELECT 0
How about using a parameter and looping through the tables?
conn.Open();
var cmd = new System.Data.SqlClient.SqlCommand(
#"SELECT count (*) FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME = #TABLE_NAME",
conn);
cmd.Parameters.Add("#TABLE_NAME", SqlDbType.VarChar);
List<String> tables = new List<string>() { "Vehicles", "Repairs" };
foreach (string tableName in tables)
{
cmd.Parameters[0].Value = tableName;
int x = Convert.ToInt32(cmd.ExecuteScalar());
if (x == 0)
CreateTable(tableName, conn);
}
conn.Close();
-- EDIT --
CreateTable method was added above, and the code would look something like this. Caveat -- this is EXTREMELY brute force, but in the absence of other information, is is one way to accomplish the task, as I best understand your issue.
private void CreateTable(String TableName, System.Data.SqlClient.SqlConnection conn)
{
StringBuilder sql = new StringBuilder(#"create table [");
sql.Append(TableName);
sql.AppendLine(#"] (");
switch (TableName)
{
case "Vehicle":
sql.AppendLine("[VIN] varchar(100),");
sql.AppendLine("[Manufacturer] varchar(100),");
sql.AppendLine("[Model] varchar(100),");
sql.AppendLine("[Year] integer");
break;
case "Repair":
sql.AppendLine("[VIN] varchar(100),");
sql.AppendLine("[Correction] varchar(100),");
sql.AppendLine("[Price] decimal");
break;
}
sql.Append(")");
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(
sql.ToString, conn);
try
{
cmd.ExecuteNonQuery();
MessageBox.Show("Created Table " + TableName);
}
catch (Exception ex)
{
MessageBox.Show("Oops, I did it again");
}
}
Wrap it in a for loop
for(int i = 0; i < 2; i++){
if (i = 0)
{
string tblnm = "Vehicle";
}
else
{
string tblnm = "Repairs";
}
SqlConnection conn;
using (conn = new SqlConnection(connection))
{
conn.Open();
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
cmd.CommandText = #"IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME='" + tblnm + "') SELECT 1 ELSE SELECT 0"; ;
cmd.Connection = conn;
cmd.ExecuteNonQuery();
int x = Convert.ToInt32(cmd.ExecuteScalar());
conn.Close();
if (x == 2)
{
MessageBox.Show("Lentelės yra");
}
else
{
MessageBox.Show("Lenteliu nėra.Sukuriama");
}
}
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().
If I put "if, foreach, and else statement under comment //", the program works and Reduces book count by 1 from SQL database. But I want to check IF there is at least 1 available book to give. This code keeps showing me the message in "else" statement if I leave it like this. Help is needed fast, it's my final project, that is needed to be done before 23.07. :(
int book_qty = 0;
SqlCommand cmd2 = connection.CreateCommand();
cmd2.CommandType = CommandType.Text;
cmd2.CommandText = "SELECT * FROM Book_list WHERE BookName = '" + TextBoxBookName + "'";
cmd2.ExecuteNonQuery();
DataTable dt2 = new DataTable();
SqlDataAdapter da2 = new SqlDataAdapter(cmd2);
da2.Fill(dt2);
foreach (DataRow dr2 in dt2.Rows)
{
book_qty = Convert.ToInt32(dr2["book_qty"].ToString());
}
if (book_qty > 0)
{
SqlCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO Issue_book VALUES(" + TextBoxSearchMembers.Text + ",'" + TextBoxMemberName.Text + "','" + TextBoxMemberContact.Text + "','" + TextBoxMemberEmail.Text + "','" + TextBoxBookName.Text + "', '" + DateTimePicker1.Text + "')";
cmd.ExecuteNonQuery();
SqlCommand cmd1 = connection.CreateCommand();
cmd1.CommandType = CommandType.Text;
cmd1.CommandText = "UPDATE Book_list SET BookAvailability = BookAvailability-1 WHERE BookName ='" + TextBoxBookName.Text + "'";
cmd1.ExecuteNonQuery();
MessageBox.Show("successful issue");
this.Close();
else
{
MessageBox.Show("Book not available");
}
You are only checking book_qty from the last row in your result set instead of BookAvailability for all rows. You probably want to do something like:
SqlCommand cmd2 = connection.CreateCommand();
cmd2.CommandType = CommandType.Text;
cmd2.CommandText = "SELECT BookAvailability FROM Book_list WHERE BookName = '" + TextBoxBookName + "'";
var result = cmd2.ExecuteScalar();
book_qty = Convert.ToInt32(result);
You need to make sure that there is only one book with the given bookname available.
In that case just correcting this one line in your code would help as well:
book_qty = Convert.ToInt32(dr2["book_qty"].ToString());
to
book_qty = Convert.ToInt32(dr2["BookAvailability"].ToString());
Otherwise you'd need to query SUM(BookAvailability), but the following code would decrease the amount of books for multiple books at once, that wouldn't be good.
Untested code. I don't have your database. Comments and explanation in line.
private void OPCode()
{
try
{
//keep your connections close to the vest (local)
using (SqlConnection connection = new SqlConnection())
//a using block ensures that your objects are closed and disposed
//even if there is an error
{
using (SqlCommand cmd2 = new SqlCommand("SELECT BookAvailability FROM Book_list WHERE BookName = #BookName", connection))
{
//Always use parameters to protect from sql injection
//Also it is easier than fooling with the single quotes etc.
//If you are referring to a TextBox you need to provide what property is
//being accessed. I am not in a WPF right now and not sure if .Text
//is correct; may be .Content
//You need to check your database for correct data type and field size
cmd2.Parameters.Add("#BookName", SqlDbType.VarChar, 100).Value = TextBoxBookName.Text;
//A select statement is not a non-query
//You don't appear to be using the data table or data adapter
//so dump them extra objects just slow things dowm
connection.Open();
//Comment out the next 2 lines and replaced with
//Edit Update
//var returnVal = cmd2.ExecuteScalar() ?? 0;
//if ((int)returnVal > 0)
//*************************************************************
//Edit Update
//*************************************************************
//in case the query returns a null, normally an integer cannot
//hold the value of null so we use nullable types
// the (int?) casts the result of the query to Nullable of int
Nullable<int> returnVal = (int?)cmd2.ExecuteScalar();
//now we can use the .GetValueOrDefault to return the value
//if it is not null of the default value of the int (Which is 0)
int bookCount = returnVal.GetValueOrDefault();
//at this point bookCount should be a real int - no cast necessary
if (bookCount > 0)
//**************************************************************
//End Edit Update
//**************************************************************
{
using (SqlCommand cmd = new SqlCommand("INSERT INTO issue_book VALUES(#SearchMembers etc", connection))
{
//set up the parameters for this command just like the sample above
cmd.Parameters.Add("#SearchMembers", SqlDbType.VarChar, 100).Value = TextBoxSearchMembers.Text;
cmd.ExecuteNonQuery();
}
using (SqlCommand cmd1 = new SqlCommand("UPDATE Book_list SET BookAvailability = BookAvailability-1 WHERE BookName = #BoxBookName;", connection))
{
cmd1.Parameters.Add("#BoxBookName", SqlDbType.VarChar, 100);
cmd1.ExecuteNonQuery();
}
MessageBox.Show("success");
this.Close();
}
else
{
MessageBox.Show("Book not available");
}
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
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.
How can I check if a table already exists before creating a new one?
Updated Code:
private void checkTable()
{
string tableName = quotenameTxt.Text + "_" + firstTxt.Text + "_" + surenameTxt.Text;
string connStr = #"Data Source=|DataDirectory|\LWADataBase.sdf";
// SqlCeConnection conn = new SqlCeConnection(connStr);
// if (conn.State == ConnectionState.Closed) { conn.Open(); }
using (SqlCeConnection conn = new SqlCeConnection(connStr))
{
conn.Open();
SqlCeCommand cmd = new SqlCeCommand(#"SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #tname", conn);
cmd.Parameters.AddWithValue("#tname", tableName);
SqlCeDataReader reader = cmd.ExecuteReader();
if(reader.Read()){
MessageBox.Show("Table exists");}
else{
MessageBox.Show("Table doesn't exist");
createtable();}
Sql Server Compact supports the INFORMATION_SCHEMA views
using (SqlCeConnection conn = new SqlCeConnection(connStr))
{
conn.Open();
SqlCeCommand cmd = new SqlCeCommand(#"SELECT TOP 1 *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #tname", conn);
cmd.Parameters.AddWithValue("#tname", tableName)
SqlCeDataReader reader = cmd.ExecuteReader();
if(reader.Read())
Console.WriteLine("Table exists");
else
Console.WriteLine("Table doesn't exist");
}
EDIT
In version 3.5 it seems that the TOP 1 instruction is not accepted. However, given the WHERE clause it should make no difference using it or not so, to make it work just change the query to
SqlCeCommand cmd = new SqlCeCommand(#"SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #tname", conn);
SECOND EDIT
Looking at the code that creates the table.
(It is In chat, I suggest to add it to the question for completeness)
using (SqlCeCommand command = new SqlCeCommand(
"CREATE TABLE ['" + tableName + "'] " +
"(Weight INT, Name NVARCHAR, Breed NVARCHAR)", con))
The single quotes around the tableName variables becomes part of the name of the table. But the check for table exists doesn't use the quotes. And your code fall through the path that tries to create again the table with the quotes. Just remove the quotes around the name. They are not needed.
You can use the SqlClientConnection to get list of all objects in the db.
private void checkTable()
{
string tableName = quotenameTxt.Text + "-" + firstTxt.Text + "-" + surenameTxt.Text;
string connStr = #"Data Source=|DataDirectory|\LWADataBase.sdf";
using (SqlCeConnection conn = new SqlCeConnection(connStr))
{
bool isTableExist = conn.GetSchema("Tables")
.AsEnumerable()
.Any(row => row[2] == tableName);
}
if (!isTableExist)
{
MessageBox.Show("No such data table exists!");
}
else
{
MessageBox.Show("Such data table exists!");
}
}
Source: https://stackoverflow.com/a/3005157/1271037
I want to check if record exists or not if it exists i dont want to insert if it bot i want to insert the data in ms access database in c#.
OleDbCommand cmd = new OleDbCommand("insert into MyTable values('" + test + "','" + test + "','" + "123" + "');", con);
OleDbCommand cmd1 = new OleDbCommand("select * from MyTable", con);
temp = 0;
try
{
con.Open();
string count = (string)cmd1.ExecuteScalar();
temp = cmd.ExecuteNonQuery();
if (temp > 0)
{
MessageBox.Show("One Record Added");
}
else
{
MessageBox.Show("Record not added");
}
}
catch
{ }
Can Anyone suggest me some code.
Thanks In Advance.
Filter your Select query on the basis of some key . Check if it returns for existence or non-existence of the particular record and do the processing required .
string cmdStr = "Select count(*) from MyTable where id = 1"; //get the existence of the record as count
OleDbCommand cmd = new OleDbCommand(cmdStr, conn);
int count = (int)cmd.ExecuteScalar();
if(count >0)
{
//record already exist
}
Modify this line
OleDbCommand cmd1 = new OleDbCommand("select * from MyTable", con);