C#/SQLCE CREATE TABLE programmatically (Auto increment + Primary key) - c#

I am trying to create a table in a SQL CE database programmatically.
Currently, I am using the following query - though I am getting an error;
string command = #"CREATE TABLE CONNECTION(" +
"connection_id INTEGER IDENTITY(1,1) PRIMARY KEY, " +
"host NVARCHAR(255), port INT, key NVARCHAR(50), " +
"last_used NVARCHAR(15));";
The error I am getting is:
There was an error parsing the query. [ Token line number = 1, Token line offset = 104, Token in error = key ]
I can't seem to figure out what I am doing wrong. I am used to MySQL and the queries are slightly different.

try enclosing key in a brackets
string command = #"CREATE TABLE CONNECTION(" +
"connection_id INTEGER IDENTITY(1,1) PRIMARY KEY, " +
"host NVARCHAR(255), port INT, [key] NVARCHAR(50), " +
"last_used NVARCHAR(15));";
Reserved Words

Related

Failed when converting the nvarchar value to to data type int and other SQL Server errors

I have a SQL Server table like this:
create table LectureNotice
(
NoticeId int identity(1,1),
NoticeTitle varchar(50),
NoticeContent varchar(1000),
CreatedDate varchar(20),
LecturerId int,
CreatedBy varchar(50),
CourseId int,
NoticeViewNumber int
);
And I want to insert data into the table using the below query
private void btnCrudInsert_Click(object sender, EventArgs e)
{
string query = #"insert into LectureNotice values(#NoticeId, #NoticeTitle, #NoticeContent, #CreatedDate, #LecturerId,
#CreatedBy, #CourseId)";
using (SqlConnection connection = new SqlConnection(Helper.ConnectionHelper("KLAS_DB")))
{
try
{
if (connection.State == ConnectionState.Closed)
connection.Open();
SqlCommand cmd = new SqlCommand(query, connection);
cmd.Parameters.AddWithValue("#NoticeId", noticeId);
cmd.Parameters.AddWithValue("#NoticeTitle", txtTitle.Text.Trim());
cmd.Parameters.AddWithValue("#NoticeContent", txtContent.Text.Trim());
cmd.Parameters.AddWithValue("#CreatedDate", txtCreatedDate.Text.ToString().Trim());
cmd.Parameters.AddWithValue("#LecturerId", int.Parse(txtLecturerId.Text.Trim()));
cmd.Parameters.AddWithValue("#CreatedBy", txtLecturer.Text.Trim());
cmd.Parameters.AddWithValue("#CourseId", int.Parse(txtCourseId.Text));
cmd.ExecuteNonQuery();
}
catch (Exception ex) {
MessageBox.Show("btnCrudInsert" + ex.Message);
}
connection.Close();
}
}
When I executed the query few errors occurred. Those are as the following:
I try to insert 2021-05-28 in the text box, then the error says failed when converting nvarchar value to type int. Even in the SQL Server table I defined createdDate as varchar.
In the CreatedBy column when I insert value into, the error also says failed when converting nvarchar value to type int.
Final error is in the NoticeContent I set varchar(max) but when I insert value into it through a text box, the error says binary or string value would be truncated.
Bonus that my LectureNotice table is inherited from 2 other tables are
create table Course
(
CourseId int,
CourseName varchar(50),
CourseType varchar(50),
CourseCredit int,
Enrollment int,
primary key(CourseId)
);
create table Lecturer
(
Id int,
FirstName varchar(50),
LastName varchar(50),
Email varchar(50),
PhoneNumber varchar(13),
Department varchar(50),
LecturerType varchar(50),
primary key(Id)
);
And some filters like
alter table LectureNotice
add constraint FK_Lnotice_CourseId
foreign key(CourseId) references Course(CourseId)
on update cascade
on delete set null;
go
alter table LectureNotice
add constraint FK_Lnotice_LecturerId
foreign key(LecturerId) references Lecturer(Id)
on update cascade
on delete set null;
go
I've tried and lookup other solutions but no one as same as me.
Always explicitly list the column in the table that you are insert into
insert into LectureNotice ( ... )
NoticeId is an identity column in the tble, why are you still inserting value into it values(#NoticeId ...) ?
When you do not specify column name in the insert statement, SQL Server will match first value to the first non identity column. In your case
Column `NoticeTitle` to `#NoticeId`
Column 'NoticeContent' to `#NoticeTitle`
Column 'CreatedDate' to `#NoticeContent`
. . .
Now do you see the problem ?
Best practice, is always specify the column name in the insert
INSERT INTO LectureNotice ( NoticeTitle, NoticeContent, CreatedDate . . .)
VALUES ( #NoticeTitle, #NoticeContent, #CreatedDate ...)
This maybe can be a clue, but is it necessary that CreatedDate in LectureNotice is a varchar instead date/datetime? I have had some issues in the past writing dates in as varchar and use them as parameters at the database. Sometimes it depends of the user settings which the SQL connection is using.
Try the following
create table LectureNotice(
NoticeId int identity(1,1),
NoticeTitle varchar(50),
NoticeContent varchar(1000),
CreatedDate datetime,
LecturerId int,
CreatedBy varchar(50),
CourseId int,
NoticeViewNumber int
);
cmd.Parameters.AddWithValue("#CreatedDate", Convert.ToDateTime(txtCreatedDate.Text));
or
cmd.Parameters.AddWithValue("#CreatedDate", DateTime.Now);
Now, for NoticeContent, is this always throwing an exception? What happens if you try the following
cmd.Parameters.AddWithValue("#NoticeContent", "Lorem ipsum dolor sit amet");

I need to create a sql server database table using visual studio(c# language) . But the name of the table has to be an input from the user

con1.Open();
cmd = new SqlCommand("create table [dbo.][" + textBox2.Text + "](sno int primary key identity(1,1),[Week] [int] not null ,Date nvarchar(30) not null,Time nvarchar(30) not null,Monday_1st_half nvarchar(20),Monday_2nd_half nvarchar(20),Tuesday_1st_half nvarchar(20),Tuesday_2nd_half nvarchar(20),Wednesday_1st_half nvarchar(20),Wednesday_2nd_half nvarchar(20),Thursday_1st_half nvarchar(20),Thursday_2nd_half nvarchar(20),Friday_1st_half nvarchar(20),Friday_2nd_half nvarchar(20),Saturday_1st_half nvarchar(20),Saturday_2nd_half nvarchar(20),Sunday_1st_half nvarchar(20),Sunday_2nd_half nvarchar(20))", con1);
cmd.ExecuteNonQuery();
con1.Close();
This query works if i give the table a hard coded name instead of the textbox.text value, a table is created.
But when i use this code it creates a table with the name 'dbo.'.
If i delete the "[dbo.]" from the query, it gives an error saying 'object is missing'. can someone help me out?.
Here's a better way to do this. First create the following stored procedure:
CREATE PROC dbo.MakeUserTable(#Tablename as SYSNAME) As
DECLARE #CleanName As SYSNAME;
SET #CleanName = QUOTENAME(#Tablename, '[');
DECLARE #sql As NVARCHAR(MAX);
SELECT #sql = 'create table [dbo].' + #CleanName + '(sno int primary key identity(1,1),[Week] [int] not null ,Date nvarchar(30) not null,Time nvarchar(30) not null,Monday_1st_half nvarchar(20),Monday_2nd_half nvarchar(20),Tuesday_1st_half nvarchar(20),Tuesday_2nd_half nvarchar(20),Wednesday_1st_half nvarchar(20),Wednesday_2nd_half nvarchar(20),Thursday_1st_half nvarchar(20),Thursday_2nd_half nvarchar(20),Friday_1st_half nvarchar(20),Friday_2nd_half nvarchar(20),Saturday_1st_half nvarchar(20),Saturday_2nd_half nvarchar(20),Sunday_1st_half nvarchar(20),Sunday_2nd_half nvarchar(20));'
PRINT 'Executing "'+#sql+'"';
EXEC(#sql);
Now change your client code to execute this instead, passing in the tablename as a parameter.
I cannot 100% guarantee that this is immune to SQL Injection attacks, but if you have to accept a tablename from a user, this is about as safe as you can get.

How can I insert into the table using SQL Server

I am stuck in this condition unable to insert into the table tbl_customer its giving error :
Arithmetic overflow error converting expression to data type int.
The statement has been terminated.
here is my table structure:
create table tbl_customer(
id int identity primary key,
cust_name varchar(50) NOT NULL,
filecode varchar(20) NOT NULL,
cust_mobile int,
cust_cnic varchar(50) NOT NULL,
cust_phone int,
cust_address varchar(200)
)
and here is the code i use to insert:
insert into tbl_customer values('Jonah Gordian','LHR001',03451119182,'11-22112-122',1212121212,'abc street 12')
and I used this code in c# to try inserting:
connclass.insert("insert into tbl_customer(cust_name,filecode,cust_mobile,cust_cnic,cust_phone,cust_address) VALUES('" + txtname.Text + "','" + txtfilecode.Text + "','" + int.Parse(txtmob.Text) + "','" + txtcnic.Text + "','" + int.Parse(txtphone.Text) + "','" + txtaddress.Text + "')");
create table tbl_customer(
id int identity primary key,
cust_name varchar(50) NOT NULL,
filecode varchar(20) NOT NULL,
cust_mobile varchar(20),
cust_cnic varchar(50) NOT NULL,
cust_phone varchar(20),
cust_address varchar(200)
)
insert into tbl_customer
(cust_name, filecode, cust_mobile, cust_cnic, cust_phone, cust_address )
values
('Jonah Gordian','LHR001','03451119182','11-22112-122','1212121212','abc street 12');
And also C# code is open to SQL injection attack, use parameters instead. ie:
string sql = #"insert into tbl_customer
(cust_name,filecode,cust_mobile,cust_cnic,cust_phone,cust_address)
VALUES
(#cust_name,#filecode,#cust_mobile,#cust_cnic,#cust_phone,#cust_address)";
using (SqlConnection con = new SqlConnection(#"server=.\SQLExpress;database=yourDbName;Trusted_Connection=yes"))
{
var cmd = new SqlCommand(sql, con);
cmd.Parameters.AddWithValue("#cust_name", txtname.Text);
cmd.Parameters.AddWithValue("#filecode", txtfilecode.Text);
cmd.Parameters.AddWithValue("#cust_mobile", txtmob.Text);
cmd.Parameters.AddWithValue("#cust_cnic", txtcnic.Text);
cmd.Parameters.AddWithValue("#cust_phone", txtphone.Text);
cmd.Parameters.AddWithValue("#cust_address", txtaddress.Text);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
You define cust_mobile as int, but try to insert 03451119182, which is clearly over the limit of 2147483647.
Change to bigint or store as a VarChar (including the leading zero).
Try like this,
CREATE TABLE tbl_customer (
id INT identity PRIMARY KEY
,cust_name VARCHAR(50) NOT NULL
,filecode VARCHAR(20) NOT NULL
,cust_mobile BIGINT --or Varchar(20)
,cust_cnic VARCHAR(50) NOT NULL
,cust_phone INT
,cust_address VARCHAR(200)
)
INSERT INTO tbl_customer
VALUES (
'Jonah Gordian'
,'LHR001'
,03451119182
,'11-22112-122'
,1212121212
,'abc street 12'
)
You have exceeded the int datatype limit. Change the datatype from int to either bigint or Varchar to resolve the issue.
Note: If you need leading Zeros then you can choose Varchar otherwise you can make use of BigInt.
You exceeded the limit of the int try with bigint
this value 3451119182
see in this link the limits
https://msdn.microsoft.com/pt-br/library/ms187745(v=sql.120).aspx

ASP.NET: Cannot add or update child row: a foreign key constraint fails

i have a strange issue in a asp.net application. I have two tables who save history of some variable changes, one with a foreign key to the other, but for some reason, mysql throws error while inserting to the second table
Cannot add or update a child row: a foreign key constraint fails (`FlowDB/tab_hist_vars_reas`, CONSTRAINT `tab_hist_vars_reas_ibfk_1` FOREIGN KEY (`HIST_REASIG_ID`) REFERENCES `tab_hist_reas` (`HIST_REASIG_ID`))
This is the code that makes the insert into the two tables (assume that local variables have values). I tested locally but when i install the site in the production environment it throws the above error.
string strcmd = "INSERT INTO tab_hist_reas (HIST_REASIG_INC,HIST_REASIG_FLOW,HIST_REASIG_STEP,HIST_REASIG_DATE,HIST_REASIG_USER)";
strcmd += string.Format("VALUES ({0}, '{1}', '{2}', NOW(), '{3}');", incident, flow, step, user);
db.executeNonQuery(strcmd);
strcmd = "SELECT last_insert_id() AS id";
int idHistory = (int)db.ExecuteScalar(strcmd);
foreach(var variable in lstVariables)
{
string strcmd = "INSERT INTO tab_hist_vars_reas (HIST_REASIG_ID,HIST_VAR_REASIG_VAR,HIST_VAR_REASIG_VALUE)";
strcmd += string.Format("VALUES ({0}, '{1}', '{2}');", idHistory, variable.Name, variable.Value);
db.executeNonQuery(strcmd);
}
Here are the table definitions.
CREATE TABLE `tab_hist_reas` (
`HIST_REASIG_ID` int(11) NOT NULL auto_increment,
`HIST_REASIG_INC` int(11) default NULL,
`HIST_REASIG_FLOW` varchar(150) default NULL,
`HIST_REASIG_STEP` varchar(150) default NULL,
`HIST_REASIG_DATE` datetime default NULL,
`HIST_REASIG_USER` varchar(150) default NULL,
PRIMARY KEY (`HIST_REASIG_ID`)
) ENGINE=InnoDB;
CREATE TABLE `tab_hist_vars_reas` (
`HIST_VAR_REASIG_ID` int(11) NOT NULL auto_increment,
`HIST_REASIG_ID` int(11) NOT NULL,
`HIST_VAR_REASIG_VAR` varchar(100) default NULL,
`HIST_VAR_REASIG_VALUE` varchar(100) default NULL,
PRIMARY KEY (`HIST_VAR_REASIG_ID`),
KEY `IND_HIST_VAR_REAS_ID_HIST` (`HIST_REASIG_ID`),
CONSTRAINT `tab_hist_vars_reas_ibfk_1` FOREIGN KEY (`HIST_REASIG_ID`) REFERENCES `tab_hist_reas` (`HIST_REASIG_ID`)
) ENGINE=InnoDB;
I tried replacing the last_insert_id() with ##identity but didn't work either. I tried executing the query directly into the database and it works fine.
A part from the Sql Injection problem that you have in your code, a probable reason for this behavior is the db variable. If this variable is some instance of a custom class that opens and closes the connection every time you call an ExecuteXXX method then you could face a problem with the SELECT LAST_INSERT_ID called in a different connection from the one that inserts the values in the first table.
You could try to merge the two initial commands to have them handled together by the same connection
string strcmd = #"INSERT INTO tab_hist_reas
(HIST_REASIG_INC,HIST_REASIG_FLOW,HIST_REASIG_STEP,
HIST_REASIG_DATE,HIST_REASIG_USER) ";
strcmd += string.Format("VALUES ({0}, '{1}', '{2}', NOW(), '{3}');", incident, flow, step, user);
strcmd += "SELECT last_insert_id() AS id";
int idHistory = (int)db.ExecuteScalar(strcmd);
In this way you exec just one command and you should be sure that the return from the SELECT last_insert_id() is effectively set to the current insert command.

AUTOINCREMENT does not work on OleDbCommand

I'm doing MS Access database file using OleDb. Here is the snippet:
OleDbCommand command = oleDbConnection.CreateCommand();
command.CommandText =
"CREATE TABLE MyTable (" +
"[Count] LONG NOT NULL PRIMARY KEY AUTOINCREMENT, " +
"[TimeAndDateTested] TIMESTAMP NOT NULL, " +
"[SerialNumber] VARCHAR(14) NOT NULL, " +
"[TestResult] BIT NOT NULL)";
command.ExecuteNonQuery();
Do you know what's wrong? Thanks.
In Access 2003, this statement will create the table structure I think you want. Notice I changed the name of the first field to Kount because Count is a reserved word in Access. You could enclose the name in square brackets to avoid ambiguity, but I prefer to just avoid using reserved words as object names. TIMESTAMP is recognized as a synonym for DATETIME. VARCHAR is recognized as a synonym for TEXT. BIT will get you a field type which Access calls Yes/No.
CREATE TABLE MyTable2 (
Kount COUNTER CONSTRAINT pkey PRIMARY KEY,
TimeAndDateTested TIMESTAMP NOT NULL,
SerialNumber VARCHAR(14) NOT NULL,
TestResult BIT NOT NULL);
I assigned a primary key constraint to Kount, and named the constraint as "pkey". Not Null and unique are implied by the primary key constraint, so you needn't specify them separately.
I change:
"[Count] LONG NOT NULL PRIMARY KEY AUTOINCREMENT, " +
with:
"[Count] IDENTITY NOT NULL PRIMARY KEY, " +
and it worked.
When using DDL against MS Access, you want to use COUNTER to specify an auto-incrementing integer Field.

Categories

Resources