I have got the following stored procedure.
ALTER PROCEDURE dbo.insert_movie
(
#first_name varchar(50),
#movie_name varchar(50),
#date date,
#last_id_inserted int,
#last_name varchar(50)
)
AS
INSERT INTO movies (movie_name,movie_date) VALUES (#movie_name,#date);
SELECT SCOPE_IDENTITY() AS scope;
INSERT INTO customer (first_name,last_name,movie_id)
VALUES (#first_name,#last_name,#last_id_inserted)
I want to insert the scope variable into #last_id_inserted.
Basically, I want to insert the last inserted id (movie_id) to the customer table..
not sure about the syntax though
You can assign the result of the function to the variable.
SET #last_id_inserted = SCOPE_IDENTITY();
There is no need to have #last_id_inserted as a parameter. Declare it as a variable in the SP.
DECLARE #last_id_inserted int;
SET #last_id_inserted = SCOPE_IDENTITY();
Or you can use it directly in the insert statement.
INSERT INTO customer (first_name,last_name,movie_id)
VALUES (#first_name,#last_name,SCOPE_IDENTITY())
SELECT #last_id_inserted = SCOPE_IDENTITY()
or
SET #last_id_inserted = SCOPE_IDENTITY()
You need to declare the variable in the stored procedure and assign the value of the SCOPE_IDENTITY function:
DECLARE #last_id_inserted int;
SET #last_id_inserted = SCOPE_IDENTITY();
I just want to add to other answers that you can add OUTPUT clause (SQLServer 2005 and higher) to your INSERT instead of using SCOPE_IDENTITY
Related
I am trying to insert asp.net grid data to database table [DBO].[tbl_family_member]. I've created a type typ_fam_mem for this. But the problem is the column family_member_id value is generated from another table [DBO].[TBL_FAMILY_HEAD]. Please look at the procedure.
How can I insert data to the table from a datatable and procedure variables?
CREATE TABLE [DBO].[tbl_family_member]
(
family_member_id bigint identity(1,1) not null,
family_head_id bigint NOT NULL,
mem_name nvarchar(200) not null,
mem_gender tinyint not null,
mem_occupation nvarchar(50),
mem_maritial_status tinyint,
STATUS INT NOT NULL DEFAULT '1',
CONSTRAINT pk_family_member PRIMARY KEY (family_member_id)
)
create type typ_fam_mem as table
(
mem_name nvarchar(200) not null,
mem_gender tinyint not null,
mem_occupation nvarchar(50),
mem_maritial_status tinyint
)
Stored procedure
CREATE PROCEDURE [dbo].[P_SET_PROFILE_REGISTRATION]
(
--- FOR FAMILY HEAD TABLE
#P_NAME NVARCHAR(200),
#P_GENDER TINYINT,
---- FOR FAMILY MEMBER
#P_FAMILY_DT DBO.typ_fam_mem READONLY,
#V_OUT TINYINT OUTPUT
)
AS
DECLARE #FAMILY_HEAD_ID BIGINT;
BEGIN
SET NOCOUNT ON;
BEGIN TRY
INSERT INTO [DBO].[TBL_FAMILY_HEAD] ([NAME], [GENDER])
VALUES (#P_NAME, #P_GENDER)
SET #FAMILY_HEAD_ID = SCOPE_IDENTITY();
IF ##ROWCOUNT > 0
BEGIN
--- block for inserting data into [DBO].[tbl_family_member]
END
END TRY
BEGIN CATCH
END CATCH
END
#P_FAMILY_DT is a table type, you can query the table type like a normal table.
Your insert should look like
INSERT INTO [DBO].[tbl_family_member]
(family_head_id,
mem_name,
mem_gender,
mem_occupationm,
mem_maritial_status)
SELECT #FAMILY_HEAD_ID,
mem_name,
mem_gender,
mem_occupation,
mem_maritial_status
FROM #P_FAMILY_DT
You can use INSERT...SELECT, specifying the variable with the generated value. The example below also adds a transaction management (appropriate for multi-table inserts unless client app manages the transaction) and error handling.
CREATE PROCEDURE [dbo].[P_SET_PROFILE_REGISTRATION]
--- FOR FAMILY HEAD TABLE
#P_NAME NVARCHAR(200),
#P_GENDER TINYINT,
---- FOR FAMILY MEMBER
#P_FAMILY_DT DBO.typ_fam_mem READONLY,
#V_OUT TINYINT OUTPUT
AS
DECLARE #FAMILY_HEAD_ID BIGINT;
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRAN;
INSERT INTO [DBO].[TBL_FAMILY_HEAD] ([NAME], [GENDER])
VALUES (#P_NAME, #P_GENDER)
SET #FAMILY_HEAD_ID = SCOPE_IDENTITY();
INSERT INTO dbo.tbl_family_member(
mem_name
, mem_gender
, mem_occupation
, mem_maritial_status
, family_head_id
)
SELECT
mem_name
, mem_gender
, mem_occupation
, mem_maritial_status
, #FAMILY_HEAD_ID
FROM #P_FAMILY_DT;
COMMIT;
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0 ROLLBACK;
THROW;
END CATCH;
GO
I have created a table with an Id column as varchar(20).
I need a stored procedure which can increment id by 1.
I have tried this:
ALTER PROCEDURE dbo.spInsertCatQuery
(#Users_Id varchar(20),
#Cat_Id varchar(20),
#Query varchar(100),
#Query_Title varchar(50)
)
AS
BEGIN
Declare #Query_Id bigint
SELECT #Query_Id = coalesce((select max(Query_Id) + 1 from tblCatQuery), 1);
INSERT INTO tblCatQuery
VALUES(#Query_Id, #Users_Id, #Cat_Id, #Query_Title, #Query)
END
But it is not working after 10th record.
Change the selection of Query_id from your table to below
SELECT #Query_Id=
coalesce((select max(cast(Query_Id as int)) + 1 from tblCatQuery), 1);
Based on Gordon's comment; my understanding is that since ID is varchar max(id) is not fetching the correct max value but casting it will do so.
For example try this
create table testtab (id varchar(10));
insert into testtab values(2),(200),(53)
If you say below it will return 53
select MAX(id) from testtab
but this one will return 200
select MAX(cast(id as int)) from testtab
Tested in SQL SERVER 2008 R2
You do know your stored procedure has an implicit race condition, don't you?
Between your calculating the new query id and your table insert getting committed, another session can come in, get exactly the same query id, insert it and get committed. Guess what happens when your insert tries to commit? First in wins; the second gets a duplicate key error. Don't ask me how I know this :)
If you really need a text query id, you might try using a computed field, something like this:
create table dbo.tblCatQuery
(
query_id int not null identity(1,1) primary key clustered ,
query_id_text as right('0000000000'+convert(varchar,id),10) ,
user_id varchar(20) not null ,
cat_id varchar(20) not null ,
query varchar(100) not null ,
query_title varchar(50) not null ,
)
Then your stored procedure looks like this:
create procedure dbo.spInsertCatQuery
#Users_Id varchar(20) ,
#Cat_Id varchar(20) ,
#Query varchar(100) ,
#Query_Title varchar(50) ,
#Query_ID varchar(10) output
AS
insert dbo.tblCatQuery ( user_id , cat_id , query_title , query )
VALUES ( #Users_Id , #Cat_Id , #Query_Title , #Query )
-- give the caller back the id of the row just inserted
set #Query_ID = ##SCOPE_IDENTITY
-- for redundancy, hand it back as the SP's return code, too
return #Query_ID
GO
It sounds like your application needs a string for the ID field, yet in the database you want it ID to behave as an auto-incrementing integer field.
Consider using an integer in the database, and when you retrieve the value and need to use it as as string, at that point convert the value to a string, either in your query or in your application.
This will solve your problem.
You must seriously review your design. I shall suggest something like this.
CREATE TABLE tblCatQuery(QueryId int NOT NULL PRIMARY KEY IDENTITY(1, 1),
UserId int NOT NULL REFERENCES tblUsers(UserId),
CatId int NOT NULL REFERENCES tblCat(CatId),
Query varchar(100), Query_Title varchar(50))
CREATE TABLE tblUsers(UserId int NOT NULL PRIMARY KEY IDENTITY(1, 1), ....
CREATE TABLE tblCat(CatId int NOT NULL PRIMARY KEY IDENTITY(1, 1), ....
CREATEPROCEDURE dbo.spInsertCatQuery
(
#Users_Id int,
#Cat_Id int,
#Query varchar(100),
#Query_Title varchar(50)
)
AS
BEGIN
INSERT INTO tblCatQuery(Users_Id, Cat_Id, Query_Title, Query)
VALUES( Users_Id, Cat_Id, Query_Title, Query)
END
ALTER PROCEDURE [dbo].[Signin_Check]
#uid varchar(50), #pwd varchar(50), #uname varchar(50) output
AS
IF EXISTS (SELECT * FROM threeLayer_user WHERE uid = #uid and pass = #pwd)
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT #uname = name
FROM threeLayer_user
WHERE uid = #uid and pass = #pwd
RETURN #uname
END
This stored procedure is throwing an error :
Conversion failed when converting the varchar value 'Saurav' to data type int.
Your code contains the line
return #uname
the return statement can only accept integer values. However, your #uname parameter is an output parameter, so you do not need to also return it. Just make sure that you specify OUTPUT when calling the sproc:
EXEC dbo.Signin_Check #uid, #password, #uname OUTPUT;
The SP doesn't seem to have bad code related to the error, could you check well the parameters being passed to the stored procedure (i.e. their order and their type)? The problem can be the values that you are passing and not the actual procedure.
Could you append to your post the code you are using when you invoke the stored procedure?
Are you sure that it's varchar column?
#uid varchar(50) / int
uid = #uid
I have a stored procedure that I return the new ID number. The code looks like this:
ALTER PROCEDURE [dbo]. [Save Contact]
#FirstName varchar (50),
#LastName varchar (50),
#Email varchar (50)
AS
BEGIN
- SET NOCOUNT ON added to Prevent extra result sets from
- Interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO Contacts (FirstName, LastName, Email)
VALUES (#FirstName, #LastName, #Email)
SELECT SCOPE_IDENTITY() as newid
END
When I try to map my stored procedures I get the following error:
Error 1 Error 2047: A mapping function binding specifier a function demoModel.Store.SaveContact with an unsupported parameter: id. Output parameters May only be mapped through the RowsAffectedParameter property. Use result bindings to return values from a function invocation.
Is there anyone here who can see what I'm doing wrong?
Need more code, let me know.
With the SQL as it is above remove id as a parameter for the insert statement. Its not needed. To get SCOPE_IDENTITY() you only need to map newid it in the Result Column Bindings.
Also ensure that the column name in Result Column Bindings is the same case as the stored procedure is returning.
Source: http://blogs.msdn.com/b/adonet/archive/2008/03/26/stored-procedure-mapping.aspx
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