I want to create insert and update sql statements in single statement. But insert statement is for one table and update statement for another table...
this is Appliance_Location table
CREATE TABLE [dbo].[Appliance_Location] (
[Appliance_Id] NCHAR (10) NOT NULL,
[RoomId] NVARCHAR (20) NOT NULL,
[ApplianceName] NCHAR (10) NOT NULL,
[AddDate] DATE NULL,
CONSTRAINT [PK_Appliance_Location] PRIMARY KEY CLUSTERED ([Appliance_Id] ASC)
);
and this is Appliance_Count table
CREATE TABLE [dbo].[Appliance_Count] (
[RoomId] NVARCHAR (20) NOT NULL,`enter code here`
[Bulb] INT NOT NULL,
[Fan] INT NOT NULL,
[AC] INT NOT NULL,
[Computer] INT NOT NULL,
CONSTRAINT [PK_Appliance_Count] PRIMARY KEY CLUSTERED ([RoomId] ASC)
);
when I insert an appliance to the Appliance_Location table then count of that particular appliance in Appliance_Count table should be updated
It is not possible to insert and update in single query. But You have one option for this task. You can create trigger to inserting of one table. And trigger through update value in other table.
Not sure how about other SQL servers, but you are allowed to execute multiple queries using the same syntax in MS SQL.
using (SqlConnection connection = CreateConnection())
{
SqlCommand command = connection.CreateCommand();
command.CommandText = #"INSERT INTO `TableA` VALUES (1, 2, 3);
UPDATE `TableB` SET [Val] = 'value' WHERE [Id] > 10";
command.CommandType = CommandType.Text;
// ... other initializations
return command.ExecuteNonQuery();
}
You even can return values:
INSERT INTO `TableC` VALUES (1, 'value');
SELECT SCOPE_IDENTITY() AS Id;
After this query you can get SQL reader and read "Id" value from the response.
Why don't you just try before asking?
Related
I have the following simple SQLite script to create a new database with a versioning table:
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS `db_versions` (
`version` integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`name` varchar ( 50 ) DEFAULT NULL UNIQUE,
`date_defined` datetime DEFAULT NULL,
`comments` text
);
INSERT INTO `db_versions` VALUES (0,'initial-create','2017-12-02 14:41:56',NULL);
COMMIT;
Running this script in the DB Browser for SQLite logs correctly logs that only 1 row is affected (inserted). However, when I try to execute this script in code with Mono (Mono.Data.Sqlite), the script apparently affects 2 rows. Here is that code:
using (var conn = new SqliteConnection(_connStr)) {
await conn.OpenAsync(cancellationToken);
using (SqliteCommand comm = conn.CreateCommand()) {
comm.CommandType = CommandType.Text;
comm.CommandText = #"
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS `db_versions` (
`version` integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`name` varchar ( 50 ) DEFAULT NULL UNIQUE,
`date_defined` datetime DEFAULT NULL,
`comments` text
);
INSERT INTO `db_versions` VALUES (0,'initial-create','2017-12-02 14:41:56',NULL);
COMMIT;
";
int rowsAffected = await comm.ExecuteNonQueryAsync(cancellationToken);
if (rowsAffected > 1) {
// Why is this code running??
}
}
}
Does anyone know why I'm getting these different results?
Gah, I figured it out. The integer version field was being defined AUTOINCREMENT, which also adds the largest ROWID to an internal sqlite_sequence table. So there was a 2nd row being added.
I'm trying to read data from a table in my Sqlite database using the Microsoft.Data.Sqlite classes in a UWP application.
There's a single row in the table, inserted by the same application. I can see the data using a Sqlite database browser, and can copy-paste the SQL query into the database browser, run it, and see the correct result returned.
However, when I run the same query using the code below, no data is returned.
string _query = "SELECT [Source] FROM [Sessions] ORDER BY [MinTimeOffset];";
_SessionList = new List<string>();
using (SqliteCommand _command = new SqliteCommand(_query, _Connection))
{
using (SqliteDataReader _reader = _command.ExecuteReader())
{
while (_reader.Read())
{
_SessionList.Add((string)_reader["Source"]);
}
}
}
The table structure is as follows:
CREATE TABLE Sessions (
[Id] INTEGER PRIMARY KEY AUTOINCREMENT,
[Source] NVARCHAR(255) NOT NULL,
[MinValue] FLOAT NULL,
[MaxValue] FLOAT NULL,
[MinTimeOffset] BIGINT NULL,
[MaxTimeOffset] BIGINT NULL
)
And the data is:
1, "2017-09-17-070007-ELEMNT BOLT BDA2-15-0.fit", NULL, NULL, NULL, NULL
No exceptions are thrown, _reader.Read() returns false the first time it is called, and _reader.HasRows is false, suggesting no data is returned by the query.
I'm sure there's something simple I'm missing here - what could cause this?
Update following comments:
I can use ExecuteScalar() to retrieve data from the same table without a problem, although this is performed as part of a transaction alongside thousands of inserts, so I guess is slightly different. The code for that, which works, is as follows:
_query = "SELECT [Id] FROM Sessions WHERE [Source] = #sessionName LIMIT 1;";
long _sessionId;
_IngestCommand.CommandText = _query;
_IngestCommand.Parameters.Add(new SqliteParameter("#sessionName", sessionName));
_sessionId = (long)_IngestCommand.ExecuteScalar();
Regarding how I connection, the database is either a new database created from scratch via DDL statements, or an existing version created in the same manner. It makes no difference which of those two methods I use. There's only one database file at any time - I'm deleting the folder contents manually before running to be sure I'm not opening any copies or old versions etc, then creating the database programmatically and inserting a bunch of data into it in a transaction, including a record into this table which is successfully retrieved as part of the insert logic, then committing the transaction.
At this point I can browse all of the inserted data in a Sqlite database browser. Then I'm calling the method which includes the ExecuteReader() code shown above and receiving no results. The same connection is used throughout - it's opened in a class constructor and closed in the Dispose() method of that class (I know that's not great design - I'm going to refactor it once I've got this figured out. The connection code is shown below:
var _connSB = new SqliteConnectionStringBuilder
{
Cache = SqliteCacheMode.Private,
DataSource = filename,
Mode = SqliteOpenMode.ReadWriteCreate
};
_Connection = new SqliteConnection(_connSB.ToString());
_Connection.Open();
And the code that builds the database:
string[] _commands = {
"CREATE TABLE IF NOT EXISTS ProjectMetaData ([Id] INTEGER PRIMARY KEY AUTOINCREMENT, [Name] NVARCHAR(100) NOT NULL, [Value] NVARCHAR(255) NOT NULL)",
"CREATE TABLE IF NOT EXISTS Series ([Id] INTEGER PRIMARY KEY AUTOINCREMENT, [Name] NVARCHAR(100) NOT NULL, [Unit] NVARCHAR(48) NOT NULL, [MinValue] FLOAT NULL, [MaxValue] FLOAT NULL, [MinTimeOffset] BIGINT NULL, [MaxTimeOffset] BIGINT FLOAT NULL)",
"CREATE TABLE IF NOT EXISTS Sessions ([Id] INTEGER PRIMARY KEY AUTOINCREMENT, [Source] NVARCHAR(255) NOT NULL, [MinValue] FLOAT NULL, [MaxValue] FLOAT NULL, [MinTimeOffset] BIGINT NULL, [MaxTimeOffset] BIGINT NULL)",
"CREATE TABLE IF NOT EXISTS Data ([Id] INTEGER PRIMARY KEY AUTOINCREMENT, [SeriesId] INT NOT NULL, [SessionId] NOT NULL, [TimeOffset] BIGINT NOT NULL, [Value] FLOAT NOT NULL, [Discounted] BIT NULL)"
};
foreach (string _command in _commands)
{
using (SqliteCommand _dbCommand = new SqliteCommand(_command, _Connection))
{
_dbCommand.ExecuteNonQuery();
}
}
I have a database connection where i insert data into the table having 2 columns i.e. id,first_name,last_name.
Following is the code:
private void Insert_Click(object sender, EventArgs e)
{
try
{
String query = "INSERT INTO data_table (first_name,last_name) VALUES (#f_name,#l_name)";
using (SqlConnection connection1 = new SqlConnection(
Properties.Settings.Default.DatabaseConnection))
using (SqlCommand insertCommand = new SqlCommand(query, connection1))
{
//a shorter syntax to adding parameters
// insertCommand.Parameters.Add("#id", SqlDbType.Int).Value = 1;
insertCommand.Parameters.Add("#f_name", SqlDbType.NChar).Value = "JAVED";
insertCommand.Parameters.Add("#l_name", SqlDbType.NChar).Value = "GHAMJN";
//make sure you open and close(after executing) the connection
connection1.Open();
insertCommand.ExecuteNonQuery();
connection1.Close();
MessageBox.Show("Record inserted. Please check your table data. :)");
}
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
Following is T-SQL script:
CREATE TABLE [dbo].[data_table] (
[Id] INT NOT NULL IDENTITY,
[first_name] NCHAR (10) NULL,
[last_name] NCHAR (10) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
The issue is created by id: I have set it auto-increment.
When i click insert button a MessageBox pops saying:
Cannot insert the value NULL into column 'Id',table 'C:\Users.......\Database1.MDF.dbo.data_table;column doesn't allows null.INSERT fails
Add identity seed and increment values to your table...
CREATE TABLE [dbo].[data_table] (
[Id] INT NOT NULL IDENTITY(1,1),
[first_name] NCHAR (10) NULL,
[last_name] NCHAR (10) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
Your Id field should be modified as shown below
Deleting that table alongwith all the old copies of old table and creating a new table with suggested Identity(1,1) resolved the issue
try this. The behaviour of Identity Columns can be selectively enabled or disabled with this statement.
If your Identity Column is configured correctly, then this is the only logical explanation for it not behaving as expected
SET IDENTITY_INSERT [dbo].[data_table] ON;
However, it is more likely that your assertion of correctness is flawed and you have not configured the Identity Column correctly.
So I have two tables, Employee and Login:
CREATE TABLE [dbo].[Employee] (
[EmpID] INT IDENTITY (1, 1) NOT NULL,
[ManagerID] INT NULL,
[EmpName] VARCHAR (50) NOT NULL,
[EmpRank] VARCHAR (50) NOT NULL,
[EmpDateOfBirth] DATE NOT NULL,
[EmpAddress] VARCHAR (100) NOT NULL,
[DeptID] INT NOT NULL,
[EmpSalary] INT DEFAULT ((0)) NOT NULL,
[EmpGender] VARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([EmpID] ASC),
CONSTRAINT [FK_Employee_Department] FOREIGN KEY ([DeptID]) REFERENCES [dbo].[Department] ([DeptID])
and
CREATE TABLE [dbo].[Login] (
[Username] VARCHAR (50) NOT NULL,
[Password] VARCHAR (50) NOT NULL,
[EmpID] INT NOT NULL IDENTITY,
PRIMARY KEY CLUSTERED ([Username] ASC),
CONSTRAINT [FK_Login_Employee] FOREIGN KEY ([EmpID]) REFERENCES [dbo].[Employee] ([EmpID])
So I have a page form to create a new Employee, which adds info to both the Employee and Login tables. With the Employee table this works fine, but with the Login table, I get an exception in Visual Studio as EmpID 'cannot be null', even though like in the Employee table it is also set to Identity. The exception occurs even if it's not set to Identity. So I'm wondering what I can do so that I can add a new Employee while keeping the same EmpID for the new record in both tables.
This is what the C# code to add the new info looks like:
SqlCommand sqlc = new SqlCommand("Insert into Employee(EmpName, EmpRank, EmpDateOfBirth, EmpGender, DeptID, EmpSalary, EmpAddress) values (#EmpName, #EmpRank, #EmpDateOfBirth, #EmpGender, #DeptID, #EmpSalary, #EmpAddress)", connect);
sqlc.Parameters.AddWithValue("#EmpName", TextBoxName.Text);
sqlc.Parameters.AddWithValue("#EmpRank", DropDownListRank.Text);
sqlc.Parameters.AddWithValue("#EmpDateOfBirth", TextBoxDateOfBirth.Text);
sqlc.Parameters.AddWithValue("#EmpGender", DropDownListGender.Text);
sqlc.Parameters.AddWithValue("#DeptID", DropDownListDepartment.Text);
sqlc.Parameters.AddWithValue("#EmpSalary", TextBoxSalary.Text);
sqlc.Parameters.AddWithValue("#EmpAddress", TextBoxAddress.Text);
SqlCommand sqlc2 = new SqlCommand("Insert into Login(Username, Password) values (#Username, #Password)", connect);
sqlc2.Parameters.AddWithValue("#Username", TextBoxUsername.Text);
sqlc2.Parameters.AddWithValue("#Password", TextBoxPassword.Text);
connect.Open();
sqlc.ExecuteNonQuery();
sqlc2.ExecuteNonQuery();
connect.Close();
Any help will be greatly appreciated.
Well, the first thing to do is to remove the IDENTITY in the Login table EmpID.
This will be the same ID of the other Employee table, so you don't want the database to generate a possible different ID for the Login table.
Second, you need to retrieve from the Employee table the last id assigned automatically by the database.
This could be achieved appending the SELECT SCOPE_IDENTITY() at the first query and retrieving the value assigned to the Employee identity column calling ExecuteScalar()
// Notice the semicolon at the end of the first query to separate
// the second command text. The result of this second command is returned
// by ExecuteScalar
SqlCommand sqlc = new SqlCommand(#"Insert into Employee(EmpName, EmpRank, EmpDateOfBirth,
EmpGender, DeptID, EmpSalary, EmpAddress)
values (#EmpName, #EmpRank, #EmpDateOfBirth,
#EmpGender, #DeptID, #EmpSalary, #EmpAddress);
SELECT SCOPE_IDENTITY()", connect);
sqlc.Parameters.AddWithValue("#EmpName", TextBoxName.Text);
sqlc.Parameters.AddWithValue("#EmpRank", DropDownListRank.Text);
sqlc.Parameters.AddWithValue("#EmpDateOfBirth", TextBoxDateOfBirth.Text);
sqlc.Parameters.AddWithValue("#EmpGender", DropDownListGender.Text);
sqlc.Parameters.AddWithValue("#DeptID", DropDownListDepartment.Text);
sqlc.Parameters.AddWithValue("#EmpSalary", TextBoxSalary.Text);
sqlc.Parameters.AddWithValue("#EmpAddress", TextBoxAddress.Text);
connect.Open();
int empid = Convert.ToInt32(sqlc.ExecuteScalar());
// Now pass the empid value to the second table
// Remember to remove the IDENTITY flag from Login.EmpID otherwise
// you will get an error.
SqlCommand sqlc2 = new SqlCommand(#"Insert into Login(EmpID, Username, Password)
values (#empid, #Username, #Password)", connect);
sqlc2.Parameters.AddWithValue("#empid", empid);
sqlc2.Parameters.AddWithValue("#Username", TextBoxUsername.Text);
sqlc2.Parameters.AddWithValue("#Password", TextBoxPassword.Text);
sqlc2.ExecuteNonQuery();
connect.Close();
This question already has answers here:
Is there AUTO INCREMENT in SQLite?
(9 answers)
Closed last month.
I'm new to SQLite and I'm trying to run the following code:
using (var cn = new SQLiteConnection("Data Source=:memory:;Version=3;")) {
cn.Open();
var cmd = cn.CreateCommand();
cmd.CommandText = "CREATE TABLE [ContentItems] ([Id] [int] IDENTITY(1,1) NOT NULL, [Title] [nvarchar](100) NOT NULL, CONSTRAINT [PK_ContentItems] PRIMARY KEY ([Id]))";
cmd.ExecuteNonQuery();
var cmd2 = cn.CreateCommand();
cmd2.CommandText = "INSERT INTO [ContentItems] (Title) VALUES ('Test 1')";
cmd2.ExecuteNonQuery();
}
But this gives the error:
Abort due to constraint violation ContentItems.Id may not be NULL
I've had a look through the documentation but based on my past SQL experience I cannot see why this doesn't work. I'd appreciate the help. Thanks
SQLite creates what you're thinking of as an IDENTITY column using the AUTOINCREMENT keyword. In your example, the ID column is not created with AUTOINCREMENT and, since it is declared NOT NULL, you must supply a value.
The CREATE statement you're after is:
CREATE TABLE [ContentItems] (
[Id] INTEGER AUTOINCREMENT NOT NULL,
[Title] TEXT NOT NULL,
CONSTRAINT [PK_ContentItems] PRIMARY KEY ([Id])
)
Note that SQLite uses the TEXT data type (although it will map anything containing "CHAR" to that datatype) and doesn't need or respect maximum field lengths.