ASP.NET: Cannot insert duplicate key row in object - asp.net

I have a index table to manage database on ASP.NET MVC. When I created new a product it ran out this error. What does that mean and how to fix it ?
Cannot insert duplicate key row in object 'Production.Product' with unique index 'AK_Product_rowguid'. The duplicate key value is (00000000-0000-0000-0000-000000000000).

You are missing a field in your insert. You should add something like this in your insert statement:
insert
into product
( ... -- other column names
, your_column_name
)
values
( ... -- other values
, newid()
)

00000000-0000-0000-0000-000000000000 is uniqueidentifier in sql or system.Guid in ASP. it has not been initialized yet, so i presume u are transmitting this value from ASP. Try adding a new parameter to your query with system.guid.newguid(), or system.guid.newguid.tostring if your query uses parameters.
If you are creating t-sql script to be exectued (ex: "insert into production.product values('"+TextBox1.Text+"', newid())" or "insert into production.product values('"+TextBox1.Text+"', '"+system.guid.newguid.tostring()+"')".
You can define for the uniqueidentifier column of product table a default value newid().

Related

setting default value while creating table in SQLite

I am working on SQLite. I want to create a table namely user_role with two column role_id and role_name. And there is an another table namely default that contain role_name and default_val.
I want to set Default value of role_id in the time of creating the table user_role and the Default value have to be retrieved from the table default.
I am new to SQLite and have to idea about the way to doing such recursive query. Please help.
The documentation says:
An explicit DEFAULT clause may specify that the default value is NULL, a string constant, a blob constant, a signed-number, or any constant expression enclosed in parentheses.
You would need to use a subquery, which is not allowed.
However, you could use a trigger that sets the ID if none was specified:
CREATE TRIGGER user_role_id_default
AFTER INSERT ON user_role
FOR EACH ROW
WHEN NEW.role_id IS NULL
BEGIN
UPDATE user_role
SET role_id = (SELECT default_val
FROM "default"
WHERE role_name = NEW.role_name)
WHERE rowid = NEW.rowid;
END;

How to autogenerate the username with specific string?

I am using asp.net2008 and MY SQL.
I want to auto-generate the value for the field username with the format as
"SISI001", "SISI002",
etc. in SQL whenever the new record is going to inserted.
How can i do it?
What can be the SQL query ?
Thanks.
Add a column with auto increment integer data type
Then get the maximum value of that column in the table using "Max()" function and assign the value to a integer variable (let the variable be 'x').
After that
string userid = "SISI";
x=x+1;
string count = new string('0',6-x.ToString().length);
userid=userid+count+x.ToString();
Use userid as your username
Hope It Helps. Good Luck.
PLAN A>
You need to keep a table (keys) that contains the last numeric ID generated for various entities. This case the entity is "user". So the table will contain two cols viz. entity varchar(100) and lastid int.
You can then have a function written that will receive the entity name and return the incremented ID. Use this ID concatenated with the string component "SISI" to be passed to MySQL for insertion to the database.
Following is the MySQL Table tblkeys:
CREATE TABLE `tblkeys` (
`entity` varchar(100) NOT NULL,
`lastid` int(11) NOT NULL,
PRIMARY KEY (`entity`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The MySQL Function:
DELIMITER $$
CREATE FUNCTION `getkey`( ps_entity VARCHAR(100)) RETURNS INT(11)
BEGIN
DECLARE ll_lastid INT;
UPDATE tblkeys SET lastid = lastid+1 WHERE tblkeys.entity = ps_entity;
SELECT tblkeys.lastid INTO ll_lastid FROM tblkeys WHERE tblkeys.entity = ps_entity;
RETURN ll_lastid;
END$$
DELIMITER ;
The sample function call:
SELECT getkey('user')
Sample Insert command:
insert into users(username, password) values ('SISI'+getkey('user'), '$password')
Plan B>
This way the ID will be a bit larger but will not require any extra table. Use the following SQL to get a new unique ID:
SELECT ROUND(NOW() + 0)
You can pass it as part of the insert command and concatenate it with the string component of "SISI".
I am not an asp.net developer but i can help you
You can do something like this...
create a sequence in your mysql database as-
CREATE SEQUENCE "Database_name"."SEQUENCE1" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 001 START WITH 21 CACHE 20 NOORDER NOCYCLE ;
and then while inserting use this query-----
insert into testing (userName) values(concat('SISI', sequence1.nextval))
may it help you in your doubt...
Try this:
CREATE TABLE Users (
IDs int NOT NULL IDENTITY (1, 1),
USERNAME AS 'SISI' + RIGHT('000000000' + CAST(IDs as varchar(10)), 4), --//getting uniqueness of IDs field
Address varchar(150)
)
(not tested)

ASP.NET SQL Server insert error

So I've these two statements:
string insertUserData = "INSERT INTO W711_User_Data(Network_ID, F_Name, M_Name, L_NAME, Badge, Telephone, Org_Code, Org_Name, Req_Head_Network_ID)Values(#networkID1, #firstName1, #middleName1, #lastName1, #badgeNumber1, #telephone1, #orgCode1, #orgName1, #myUserName1)";
string insertReservationData = "INSERT INTO W711_Reservation_Data(ID, Network_ID, EventTitle, StartDate, EndDate, Justification) Values(null, #networkID2, #eventTitle1, #startDate1, #endDate1, #justification1)";
The network id in second string is foreign key relation with network id in first table.
The problem is: When I run the application in VS2010, it gives the error:
Can't insert explicit value for identity columnin table 'W711_Reservation_Data' when IDENTITY_INSERT is set to OFF.
Then I read to do this somewhere:
SET IDENTITY_INSERT W711_Reservation_Data ON
But it also fails and gives the same error again!
Please help
Thanks
p.s. sql server
if your id is an identity (aka auto generated from the database), just do not list the ID field in any place in the INSERT Statement, not as column name and not in the values list:
to get the ID generated by SQL Server you call SCOPE_IDENTITY in this way:
INSERT INTO W711_Reservation_Data(Network_ID, EventTitle, StartDate, EndDate, Justification) Values(#networkID2, #eventTitle1, #startDate1, #endDate1, #justification1)";
RETURN SCOPE_IDENTITY()
Edit: this is the second of your two statements, I have removed the ID and the NULL...
Why are you trying to insert null as the value for the ID column anyway? Assuming that this is the IDENTITY column that is the source of the complaint then it seems more likely you need to just leave it out of the column list and don't pass any explicit value in. i.e.
INSERT INTO W711_Reservation_Data
(Network_ID, EventTitle, StartDate, EndDate, Justification)
Values
(#networkID2, #eventTitle1, #startDate1, #endDate1, #justification1)
There might be two possibility.
1]
if Network_ID in first table is primary key auto generated then
insert data in first table.
then get latest network id from that table and
pass that network id with second query.
2].
If ID column in second table is primary key then
Do not pass null in second query.
either make auto generated or pass uniquer value in query.

Stored Procedure IDENTITY_INSERT

I'm recently change my data table, I remove column and add a new column that define as identity = True and identity seed = 1, identity increment = 1.
When i tried to insert data to this table by STORE PROCEDURE i get this exception:
An explicit value for the identity column in table 'AirConditioner' can only be specified when a column list is used and IDENTITY_INSERT is ON.
I saw that i need to add this lines:
SET IDENTITY_INSERT [dbo].[AirConditioner] ON and finally OFF
I added and its still throw an exception...
My store procedure is attached as a picture
SQL Server will take care of assigning a value to your identity column. You should remove #ID from the insert statement and remove the IDENTITY_INSERT statements.
can only be specified when a column
list is used and IDENTITY_INSERT is
ON.
You're forgetting the first condition: the column list. The column list is a (usually) optional element between the table name and values. You should specify it like:
INSERT INTO AirConditioner (ID, CategoricNumber, ...)
VALUES(#ID, #CategoricNumber, ...)
Do NOT use set identity insert on. If you have an identity, you should be letting SQL server decide what value to put in there.
ALTER PROCEDURE [dbo].[AddAirConditioner] #CategoricNumber int, #Name nvarchar(50),
#PicName nvarchar(100), #ShortDetails nvarchar(200), #Details nvarchar(2000),
#Price int, #ImagePath nvarchar(500), #AirConditionerType nvarchar(50), #COP float,
#BTU float, #ProdType nvarchar(20), #ProdIndex int
AS
INSERT INTO AirConditioner VALUES( #CategoricNumber, #Name, #PicName,
#ShortDetails, #Details, #Price, #ImagePath, #AirConditionerType, #COP,
#BTU, #ProdType, #ProdIndex)
If you need to get the ID back for using in child tables, then use scope_identity or the output clause. Look these up in Books online to see how to use.
Try placing
SET IDENTITY_INSERT [dbo].[AirConditioner] ON
GO
Before the alter procedure

INSERT IF NOT EXISTS ELSE UPDATE?

I've found a few "would be" solutions for the classic "How do I insert a new record or update one if it already exists" but I cannot get any of them to work in SQLite.
I have a table defined as follows:
CREATE TABLE Book
ID INTEGER PRIMARY KEY AUTOINCREMENT,
Name VARCHAR(60) UNIQUE,
TypeID INTEGER,
Level INTEGER,
Seen INTEGER
What I want to do is add a record with a unique Name. If the Name already exists, I want to modify the fields.
Can somebody tell me how to do this please?
Have a look at http://sqlite.org/lang_conflict.html.
You want something like:
insert or replace into Book (ID, Name, TypeID, Level, Seen) values
((select ID from Book where Name = "SearchName"), "SearchName", ...);
Note that any field not in the insert list will be set to NULL if the row already exists in the table. This is why there's a subselect for the ID column: In the replacement case the statement would set it to NULL and then a fresh ID would be allocated.
This approach can also be used if you want to leave particular field values alone if the row in the replacement case but set the field to NULL in the insert case.
For example, assuming you want to leave Seen alone:
insert or replace into Book (ID, Name, TypeID, Level, Seen) values (
(select ID from Book where Name = "SearchName"),
"SearchName",
5,
6,
(select Seen from Book where Name = "SearchName"));
You should use the INSERT OR IGNORE command followed by an UPDATE command:
In the following example name is a primary key:
INSERT OR IGNORE INTO my_table (name, age) VALUES ('Karen', 34)
UPDATE my_table SET age = 34 WHERE name='Karen'
The first command will insert the record. If the record exists, it will ignore the error caused by the conflict with an existing primary key.
The second command will update the record (which now definitely exists)
You need to set a constraint on the table to trigger a "conflict" which you then resolve by doing a replace:
CREATE TABLE data (id INTEGER PRIMARY KEY, event_id INTEGER, track_id INTEGER, value REAL);
CREATE UNIQUE INDEX data_idx ON data(event_id, track_id);
Then you can issue:
INSERT OR REPLACE INTO data VALUES (NULL, 1, 2, 3);
INSERT OR REPLACE INTO data VALUES (NULL, 2, 2, 3);
INSERT OR REPLACE INTO data VALUES (NULL, 1, 2, 5);
The "SELECT * FROM data" will give you:
2|2|2|3.0
3|1|2|5.0
Note that the data.id is "3" and not "1" because REPLACE does a DELETE and INSERT, not an UPDATE. This also means that you must ensure that you define all necessary columns or you will get unexpected NULL values.
INSERT OR REPLACE will replace the other fields to default value.
sqlite> CREATE TABLE Book (
ID INTEGER PRIMARY KEY AUTOINCREMENT,
Name TEXT,
TypeID INTEGER,
Level INTEGER,
Seen INTEGER
);
sqlite> INSERT INTO Book VALUES (1001, 'C++', 10, 10, 0);
sqlite> SELECT * FROM Book;
1001|C++|10|10|0
sqlite> INSERT OR REPLACE INTO Book(ID, Name) VALUES(1001, 'SQLite');
sqlite> SELECT * FROM Book;
1001|SQLite|||
If you want to preserve the other field
Method 1
sqlite> SELECT * FROM Book;
1001|C++|10|10|0
sqlite> INSERT OR IGNORE INTO Book(ID) VALUES(1001);
sqlite> UPDATE Book SET Name='SQLite' WHERE ID=1001;
sqlite> SELECT * FROM Book;
1001|SQLite|10|10|0
Method 2
Using UPSERT (syntax was added to SQLite with version 3.24.0 (2018-06-04))
INSERT INTO Book (ID, Name)
VALUES (1001, 'SQLite')
ON CONFLICT (ID) DO
UPDATE SET Name=excluded.Name;
The excluded. prefix equal to the value in VALUES ('SQLite').
Firstly update it. If affected row count = 0 then insert it. Its the easiest and suitable for all RDBMS.
Upsert is what you want. UPSERT syntax was added to SQLite with version 3.24.0 (2018-06-04).
CREATE TABLE phonebook2(
name TEXT PRIMARY KEY,
phonenumber TEXT,
validDate DATE
);
INSERT INTO phonebook2(name,phonenumber,validDate)
VALUES('Alice','704-555-1212','2018-05-08')
ON CONFLICT(name) DO UPDATE SET
phonenumber=excluded.phonenumber,
validDate=excluded.validDate
WHERE excluded.validDate>phonebook2.validDate;
Be warned that at this point the actual word "UPSERT" is not part of the upsert syntax.
The correct syntax is
INSERT INTO ... ON CONFLICT(...) DO UPDATE SET...
and if you are doing INSERT INTO SELECT ... your select needs at least WHERE true to solve parser ambiguity about the token ON with the join syntax.
Be warned that INSERT OR REPLACE... will delete the record before inserting a new one if it has to replace, which could be bad if you have foreign key cascades or other delete triggers.
If you have no primary key, You can insert if not exist, then do an update. The table must contain at least one entry before using this.
INSERT INTO Test
(id, name)
SELECT
101 as id,
'Bob' as name
FROM Test
WHERE NOT EXISTS(SELECT * FROM Test WHERE id = 101 and name = 'Bob') LIMIT 1;
Update Test SET id='101' WHERE name='Bob';
I believe you want UPSERT.
"INSERT OR REPLACE" without the additional trickery in that answer will reset any fields you don't specify to NULL or other default value. (This behavior of INSERT OR REPLACE is unlike UPDATE; it's exactly like INSERT, because it actually is INSERT; however if what you wanted is UPDATE-if-exists you probably want the UPDATE semantics and will be unpleasantly surprised by the actual result.)
The trickery from the suggested UPSERT implementation is basically to use INSERT OR REPLACE, but specify all fields, using embedded SELECT clauses to retrieve the current value for fields you don't want to change.
I think it's worth pointing out that there can be some unexpected behaviour here if you don't thoroughly understand how PRIMARY KEY and UNIQUE interact.
As an example, if you want to insert a record only if the NAME field isn't currently taken, and if it is, you want a constraint exception to fire to tell you, then INSERT OR REPLACE will not throw and exception and instead will resolve the UNIQUE constraint itself by replacing the conflicting record (the existing record with the same NAME). Gaspard's demonstrates this really well in his answer above.
If you want a constraint exception to fire, you have to use an INSERT statement, and rely on a separate UPDATE command to update the record once you know the name isn't taken.

Resources