This is my table as shown in image
This is my stored procedure for insert
but when I am trying to execute it with my project project shows error as below.
ERROR:
Cannot insert the value NULL into column 'SID', table 'AttDemo.dbo.StdMst'; column does not allow nulls. INSERT fails.
The statement has been terminated.
The easiest way to fix this would be to set the primary key to autoincrement / as an Identity.
Alternatively, you could change This:
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[STDMST_INSERT]
#STDNAME AS NVARCHAR (50)
AS
BEGIN
INSERT INTO (StdMst (StdName, EDate) VALUES(#STDNAME, GETDATE())
END
GO
To this:
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[STDMST_INSERT]
#STDNAME AS NVARCHAR (50)
AS
BEGIN
INSERT INTO (StdMst (SID, StdName, EDate) VALUES(IDENT_CURRENT('StdMst'), #STDNAME, GETDATE())
END
GO
The issue you are having is that your primary key does not allow NULL values and is not set to autoincrement.
Here are some useful links:
Set Primary Key as Identity
Setting key to autoincrement
Looks like you think that your SID column is an IDENTITY column, but it's not.
Related
I've created and worked with Triggers in Oracle for years however I'm unable to wrap my head around how to update a field when inserting data into a sqlite database.
All I want to do is create a trigger that automatically inserts the current DateTime into a column in the sqlite database named 'createdDate' for ANY record that is inserted.
What is the best approach to accomplish this?
Below is what I've attempted without success.
CREATE TRIGGER outputLogDB_Created_Trig
BEFORE INSERT
ON outputLog
WHEN NEW.createdDate IS NULL
BEGIN
SELECT CASE WHEN NEW.createdDate IS NULL THEN NEW.createdDate = datetime('now', 'localtime') END;
END;
The above is almost a replica of how I would implement my triggers in Oracle with some modifications of course for sqlite. The logic is basically identical.
What am I missing?
Later Edit - I can get it to work if I instead use AFTER INSERT and not using FOR EACH ROW
CREATE TRIGGER outputLog_Created_Trig
AFTER INSERT
ON outputLog
WHEN New.createdDate IS NULL
BEGIN
UPDATE outputLog
SET createdDate = datetime('now', 'localtime')
WHERE outputLog_ID = New.rowid;
END;
But why can't I just insert the record using the new value while I'm inserting it? Am I ONLY able to get this in there using an Update AFTER I've already inserted the record?
The issue I have with this is the fact that I'd like to have a NOT NULL constraint on the createdDate column. Perhaps I'm simply used to how I've done it for years in Oracle? I realize the Trigger 'should' take care of any record and force this field to NEVER be NULL. It's just that NOT being able to add the constraint for some reason makes me uneasy. Do I need to let go of this worry?
Thanks to Shawn pointing me toward an easy simple solution to my problem. All that is needed in a SQLite database to insert the current Date/Time for each record being inserted is to set the DEFAULT value on that column to CURRENT_TIMESTAMP.
Since I wanted the timestamp in my own local time see below my create table script that is the solution to my problem.
CREATE TABLE outputLog (
outputLog_ID INTEGER PRIMARY KEY ASC ON CONFLICT ROLLBACK AUTOINCREMENT
NOT NULL ON CONFLICT ROLLBACK,
outputLog TEXT,
created DATETIME DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime') )
NOT NULL )
;
I want to create a table and then initialize it with some values, in as concise manner as possible.
However, this script gets executed every time my app starts, so the insert should happen only on items that were not already added previously.
I do not want to use IGNORE directive in 'INSERT IGNORE INTO', because I do not want to ignore unexpected errors.
For some reason, INSERT INTO fails with "SQL error (1136): Column count doesn't match value count at row 1", even though the select that follows gives the values that need to be added.
Here's the failing code:
START TRANSACTION;
CREATE TABLE IF NOT EXISTS `privileges` (
`id` TINYINT NOT NULL AUTO_INCREMENT,
`label` VARCHAR(25) UNIQUE,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `privileges` (`label`)
SELECT `label` FROM (
SELECT NULL AS `label`
UNION VALUES
('item1'),
('item2')
) X
WHERE `label` IS NOT NULL
AND `label` NOT IN (SELECT `label` FROM `privileges`)
COMMIT;
Currently I am solving this by first inserting the values into a temporary table, and then performing a select on that. But why isn't the above working and is there a more concise way to do what I'm trying to do?
I'm using MariaDB 10.3.9, added missing UNIQUE constraint
Edit 2: Thanks to LukStorms for figuring out the error was related to AUTO_INCREMENT, it seems passing NULL for AUTO_INCREMENT column solves the problem like so:
INSERT INTO `privileges` (id, label)
WITH ITEMS(label) AS (VALUES
('users:read'),('users:create'),
('clients:read'),('clients:write'),
('catalog:read'),('catalog:write'),
('cart:read'),('cart:write'),
('orders:read'),('orders:write'), ('test1')
) SELECT NULL, label FROM ITEMS i
WHERE label NOT IN (SELECT label FROM `privileges`);
In MariaDb 10.3+, using a CTE with a the VALUES expression can let you assign a column name to it.
with ITEMS(label) as
(VALUES
('item1')
,('item2'))
select i.label
from ITEMS i
where not exists (select 1 from privileges p where p.label = i.label)
But somehow it gives an error when inserting into a table that has a field with an AUTO_INCREMENT. Seems like a bug to me.
However, when you insert a NULL into a an AUTO_INCREMENT field then the NULL gets ignored. But you discovered that behaviour yourself.
So this works:
INSERT INTO privileges (id, label)
WITH ITEMS(label) as (
VALUES ('item1'), ('item2')
)
SELECT null, i.label
FROM ITEMS i
WHERE NOT EXISTS (SELECT 1 FROM privileges p WHERE p.label = i.label);
Test on db<>fiddle here
Using unioned selects also works though.
INSERT INTO privileges (label)
SELECT label
FROM (
SELECT 'item1' as label UNION ALL
SELECT 'item2'
) i
WHERE NOT EXISTS (SELECT 1 FROM privileges p WHERE p.label = i.label);
db<>fiddle here
Maybe another way is to use a temporary table (that will vanish when the session expires)
CREATE TEMPORARY TABLE tmp_items (label VARCHAR(25) NOT NULL PRIMARY KEY);
INSERT INTO tmp_items (label) VALUES
('item1')
,('item2');
INSERT INTO privileges (label)
SELECT label
FROM tmp_items i
WHERE label NOT IN (SELECT DISTINCT label FROM privileges);
Test on db<>fiddle here
First, your application is trying to double-insert values. It probably shouldn't be doing that (though I can think of a few valid use cases). Consider making it so that it does not try to add data that it's already added before. If you don't have easy access to inter-instance state, pull the current list out of the database on startup before deciding what to insert.
Second, if you want labels to be unique, why is there not a unique key on the label field? At the moment, INSERT IGNORE wouldn't even work because there is nothing in your schema preventing duplicate label values. I would ask yourself why you need an auto-incrementing ID: why not just have the label, and make it the primary key?
Then, if you still need to do this duplicate-elision at the SQL layer, you may use ON DUPLICATE KEY to suck up redundant inserts of an existing primary key:
INSERT INTO `privileges` (`label`)
VALUES
('item1'),
('item2')
)
ON DUPLICATE KEY UPDATE `label` = `label`
This solution is difficult to implement with your auto-increment ID key, because your application probably doesn't know what the ID is going to be. Another reason to consider dropping it.
Unfortunately, there's no ON DUPLICATE KEY IGNORE.
If you want to keep the ID key, and you don't want your application to do a read step on startup (perhaps for scalability reasons), then INSERT IGNORE to be quite honest is your best bet, though you're still going to need at least a unique key on label to make that work.
I have a page bank transfer that contains a column "transfer Number" in my asp.net application. This is an auto generated column. I am taking this value based based on the query:
IF (SELECT COUNT(1) FROM tableName) = 0
SELECT IDENT_CURRENT('tableName')
ELSE
SELECT IDENT_CURRENT('tableName') + 1
The problem is when two user login, it shows same transfer number for this page. How can I show different Transfer number for different users before inserting a record?
Thanks.
set the column as identity and the values will be generated automatically, and after insert, you can get the inserted id from the variable ##identity. Like this
Table Design
CREATE TABLE YourTable
(
SeqNo INT IDENTITY(1,1) PRIMARY KEY,
Col1 VARCHAR(50),
Col2 INT,
...
)
I have set the column SeqNo as Identity and Primary key.
Identity(1,1) means the first value will be 1 and then for each row the increment will be +1 and so on.
Now I insert a record to the table
INSERT INTO YourTable(Col1,Col2)
values('abc',1)
select ##identity
Now after the insert, the 2nd select will return me the value 1 as the value of the identity field is 1.
If I run this one more time, I will get 2 and so on
You can also call the System defined function SCOPE_IDENTITY() (in case triggers are involved) instead on ##IDENTITY
You can avoid conflicts using this since the values are generated by the database itself
Ho can i define a integer auto increment with oracle 11g?This is my code with mysql user_id int(6) not null auto_increment primary key how can i have this line with oracle?Because i've already the same database in mysql now i want to build the same structure with oracle
You can achieve this with a sequence.
CREATE SEQUENCE seq_user;
The above will auto increment by 1, and start at 1.
To insert values using this sequence, you can do the following (for example):
INSERT INTO table_name (user_id) VALUES (seq_user.NEXTVAL);
To automate this process, you could reference the sequence in a trigger on the table, that adds this value on an insert automatically:
CREATE OR REPLACE TRIGGER user_trg
BEFORE INSERT ON table_name
FOR EACH ROW
DECLARE
BEGIN
IF(inserting)
THEN
:NEW.USER_ID := seq_user.NEXTVAL;
END IF;
END;
I have a script below - I dont know if it will produce the same effect as auto increment. When i begin inserting rows into my database, i dont want to insert the id. I want the database to generate and insert them automatically when i insert non-id rows.
CREATE TABLE myschema.mytable
(id NUMBER PRIMARY KEY NOT NULL,
name VARCHAR2(30));
CREATE SEQUENCE myschema.test1_sequence
START WITH 1
INCREMENT BY 1;
create or replace trigger myschema.auto_increment
before insert on myschema.mytable
for each row
begin
select test1_sequence.nextval into :new.id from dual;
end;
/
Yes it will work, except that you don't have to use
id NUMBER PRIMARY KEY NOT NULL
because PRIMARY KEY already contains the NOT NULL constraint, so
id NUMBER PRIMARY KEY
is enough.