I have 3 data tables to update database
Invoice table, primary key is InvoiceNo
InvoiceProduct table, primary key is InvoiceProductNo and foreign key InvoiceNo
InvoiceProductExp table, primary key is InvoiceProductExpNo and foreign keys are InvoiceNo and InvoiceProductNo
Facts:
One InvoiceNo has many InvoiceProductNo
one InvoiceProductNo has many InvoiceProductExpNo
3 Data Tables data entry would be for example is
Invoice (InvoiceNo,...)
(0001,...)
InvoiceProduct (InvoiceProductNo, InvoiceNo)
(1,0001,...)
(2,0001,...)
InvoiceProductExp (InvoiceProductExpNo,InvoiceProductNo,InvoiceNo)
(1,1,0001,...)
(2,1,0001,...)
(3,2,0001,...)
(4,2,0001,...)
The problem is I liked to use SQL Server generated Identity column for all primary keys of 3 tables
How can I prepare for insert statements?
Insert Into InvoiceProductExp values (auto_number, ?, ?)
How can I get InvoiceProductNo to insert into InvoiceProductExp table since InvoiceProductNo is auto number?
You're looking for SCOPE_IDENTITY()
DECLARE #InvoiceNo INT
DECLARE #InvoiceProductNo INT
INSERT INTO Invoice ([Date])
VALUES (GETDATE())
SELECT #InvoiceNo = SCOPE_IDENTITY()
INSERT INTO InvoiceProduct([InvoiceNo])
VALUES (#InvoiceNo)
SELECT #InvoiceProductNo = SCOPE_IDENTITY()
INSERT INTO InvoiceProductExp ([InvoiceProductNo], [InvoiceNo])
VALUES (#InvoiceProductNo, #InvoiceNo)
Here is SQLFiddle demo
If your primary keys are of identity column type then you don't have to insert a value into the primary key column. The identity column will auto populate when the row is committed to the database.
Does this resolve your question?
Why must manually? You can set your ID as automatically auto increment.
When you create table:
UserID INT IDENTITY(1,1) NOT NULL
sample (create the table)
CREATE TABLE dbo.Tool(
UserID INT IDENTITY NOT NULL PRIMARY KEY,
Name VARCHAR(40) NOT NULL
)
Inserting values
INSERT INTO dbo.Tool(Name) VALUES ('Person 1')
INSERT INTO dbo.Tool(Name) VALUES ('Person 2')
Related
So I've been going through SQL migrations to insert data in a SEQUENTIAL manner specifically from parent to child.
I've inserted data in the parent table. Now I've to store the primary key value of that
specific row (WHERE condition is defined in query for reference " where description = '1234'") in a variable.
And while inserting data to the child table I've to use that primary key value stored in a variable in place of a foreign key column("country_code_id") of the child table.
I'm using Postgresql
CREATE TABLE Countries
(
id SERIAL,
description VARCHAR(100),
CONSTRAINT coutry_pkey PRIMARY KEY (id)
);
CREATE TABLE Cities
(
country_code_id int ,
city_id int,
description VARCHAR(100),
CONSTRAINT cities_pkey PRIMARY KEY (city_id),
CONSTRAINT fk_cities_countries FOREIGN KEY (country_code_id) REFERENCES Countries (id)
);
INSERT INTO COUNTRIES (description) VALUES('asdf');
#countrid = SELECT id FROM COUNTRIES WHERE description = 'asdf';
INSERT INTO cities VALUES (countrid, 1 , 'abc');
SQL does not have variables. The normal way to do this is to use INSERT ... RETURNING:
INSERT INTO countries (description) VALUES ('1234')
RETURNING id;
This will return the automatically generated primary key. You store that in a variable on the client side and run a second statement:
INSERT INTO cities (country_code_id, city_id, description)
VALUES (4711, 1, 'abc');
where 4711 is the value returned from the first statement. To avoid hard-coding the value, you can use a prepared statement, which also will boost performance.
An alternative, more complicated, solution is to run both statements in a single statement using a common table expression:
WITH country_ids AS (
INSERT INTO countries (description) VALUES ('1234')
RETURNING id
INSERT INTO (country_code_id, city_id, description)
SELECT id, 1, 'abc'
FROM country_ids;
I have a many-to-many relationship between two tables, Users and Projects.
The table that connects those two together is named ProjectsUsers.
Here is the description of the tables and their relationships:
CREATE TABLE "Users"
(
Email VARCHAR(320) COLLATE SQL_Latin1_General_CP1_CI_AS PRIMARY KEY CHECK(LEN(Email) >= 3),
--More....
);
CREATE TABLE "Projects"
(
ProjectID INT PRIMARY KEY IDENTITY,
--More....
);
CREATE TABLE "ProjectsUsers"
(
UsersEmail VARCHAR(320) COLLATE SQL_Latin1_General_CP1_CI_AS CHECK(LEN(UsersEmail) >= 3) NOT NULL,
ProjectsID INT NOT NULL,
CONSTRAINT ProjectsUsers_PK PRIMARY KEY (UsersEmail, ProjectsID),
CONSTRAINT ProjectsID_FK FOREIGN KEY (ProjectsID) REFERENCES Projects (ProjectID)
ON DELETE CASCADE ON UPDATE CASCADE ,
CONSTRAINT UsersEmail_FK FOREIGN KEY (UsersEmail) REFERENCES Users(Email)
ON DELETE CASCADE ON UPDATE CASCADE
);
I am now trying to create a stored procedure that will insert a new project to the Projects table. After I add the project I want to create a reference to it in the ProjectsUsers table. The problem is, there is no possible way for me to know what the id of the project I just created - thus, I am unable to know what ID should I insert into the ProjectsUsers.
So if my stored procedure was something like this:
INSERT INTO Projects (Project, CreationDate, ProjectName)
VALUES (#project, GETDATE(), #email);
INSERT INTO ProjectsUsers VALUES (#email, ???)
How can I get the ID?
Just use SCOPE_IDENTITY like this:
INSERT INTO Projects (Project, CreationDate, ProjectName)
VALUES (#project, SYSDATETIME(), #email);
DECLARE #ProjectID INT = SCOPE_IDENTITY();
INSERT INTO ProjectsUsers
VALUES (#email, #ProjectID)
More all the relevant details about SCOPE_IDENTITY on the official Microsoft Documentation site.
As Sean Lange mentions, you can use SCOPE_IDENTITY to get last id inserted from within your proc
You can also use the OUTPUT clause and get possibly many ids. You can output in the screen or in a table, but it wont work if you are selecting from a table that has triggers.
Use the OUTPUT clause! Do not use the various identity functions or variables. This directly solves your problem:
DECLARE #ids TABLE (ProjectId int);
INSERT INTO Projects (Project, CreationDate, ProjectName)
OUTPUT inserted.ProjectId INTO #ids;
VALUES (#project, GETDATE(), #email);
INSERT INTO ProjectsUsers (UsersEmail, ProjectId)
SELECT #email, ProjectId
FROM #ids;
All the other methods of returning the identity have peculiarities:
Perhaps they don't work when the insert has multiple statements.
Perhaps concurrent inserts mess up the value.
Perhaps they don't work well with triggers.
So I have a problem, I was wondering is there a way of inserting the (ID VALUES) to each column since I forgot. I have a really long code. Is there a way for me to select a piece of code to paste the number ID values or a Method of some sort? Or is my only option to do it manually?
CREATE TABLE tASTON
(AsM_ID int Primary Key Not Null IDENTITY(1,1),Make Nvarchar(50), Model nvarchar (50))
Insert into tASTON(AsM_ID,Make,Model) Values ('Aston Martin','DB4')
Insert into tASTON (AsM_ID,Make,Model) Values ('Aston Martin','DB5')
Insert into tASTON (AsM_ID,Make,Model) Values ('Aston Martin','DB6')
Insert into tASTON (AsM_ID,Make,Model) Values ('Aston Martin','DB7')
Insert into tASTON (AsM_ID,Make,Model) Values ('Aston Martin','Vanquish') etc...
Seeing it's an IDENTITY column, there's no need to manually INSERT values. This ought to work:
Insert into tASTON(Make,Model) Values ('Aston Martin','DB4')
Update: Removed brand, as it was confusing and a mistake on my part. Replaced Brand with Make, instead.*
Unrelated, but judging by the name of the table, are you really creating one table per brand of car? If so, I'd suggest creating a make and a car table, where you then implement a key relationship between tCar and tMake:
CREATE TABLE tCAR
(
CAR_ID int Primary Key Not Null IDENTITY(1,1)
, MAKE_ID int FOREIGN KEY REFERENCES tMake(MAKE_ID)
, Model nvarchar (50)
)
Are Foreign Keys in SQL Server 2008 are automatically indexed with a value? For Example. if I add a value in my Primary key (or auto incremetend) in may parent table will the table that has a foreign key referenced to that key will automatically have the same value? or I Have to do it explicitly?
No, if you create a foreign key in a child table, it will not automatically get populated when a parent row gets inserted. If you think about this it makes sense. Let's say you have a table like:
CREATE TABLE dbo.Students
(
StudentID INT IDENTITY(1,1) PRIMARY KEY,
Name SYSNAME
);
CREATE TABLE dbo.StudentLoans
(
LoanID INT IDENTITY(1,1) PRIMARY KEY,
StudentID INT FOREIGN KEY REFERENCES dbo.Students(StudentID),
Amount BIGINT -- just being funny
);
What you are suggesting is that when you add a row to Students, the system should automatically add a row to StudentLoans - but what if that student doesn't have a loan? If the student does have a loan, what should the amount be? Should the system pick a random number?
Typically what will happen in this scenario is that you'll be adding a student and their loan at the same time. So if you know the loan amount and the student's name, you can say:
DECLARE
#Name SYSNAME = N'user962206',
#LoanAmount BIGINT = 50000,
#StudentID INT;
INSERT dbo.Students(Name)
SELECT #Name;
SELECT #StudentID = SCOPE_IDENTITY();
INSERT dbo.StudentLoans(StudentID, Amount)
SELECT #StudentID, #LoanAmount;
I've created a insert stored procedure with two tables like in the exapmle:
Table NameAge
CREATE TABLE [dbo].[Assignment3_NameAge]
(
userID int PRIMARY KEY IDENTITY(1,1),
Name varchar(255) NOT NULL,
Age int NOT NULL
)
Table Hobbies
CREATE TABLE [dbo].[Assignment3_Hobbies]
(
hobbiesID int Identity(1,1) Primary Key,
userID int Foreign Key references Assignment3_NameAge(userID),
hobbies varchar(255) NOT NULL,
)
Insert Stored Procedure
CREATE PROCEDURE [dbo].p_Assignment3Join_ins
#Name nvarchar(100),
#Age int,
#Hobbies nvarchar(100)
AS
INSERT INTO [TABLE].[dbo].[Assignment3_NameAge]
([Name]
,[Age])
VALUES (#Name,#Age)
INSERT INTO [TABLE].[dbo].[Assignment3_Hobbies]
([Hobbies])
VALUES (#Hobbies)
The problem is that when i run the stored procedure the table Hobbies has a null value for userid(the foreign key)
What am i doing wrong?
You should provide the key of the Assignment3_NameAge value you want to insert into Assignment3_Hobbies.
If you want the last inserted you can use SCOPE_IDENTITY() from SQL Server(if you're using SQL Server) or equivalent. It will give you the last inserted value from Assignment3_NameAge
I am guessing this is SQL Server based on the IDENTITY column. Correct?
The first insert creates a user, but there is no user ID being set on the insert of the hobby. You need to capture the identity value from the first insert to be used in the second insert. Have you gon over the system functions available?
You're not supplying a value for it, SQL won't automagically fill the value in for you even though you've created a Foreign Key relationship. It's your job to populate the tables.