May I ask a question regarding for the SQL Server stored procedure?
Basically I created a table called Customers and I want to write an INSERT statement inside of the stored procedure where I have been done using CURSOR.
When I execute my CREATE stored procedure should be fine and do not have any error message and also when I execute the stored procedure using EXECUTE statement without any data entry (7, Andy, Singapore) do not have any error message.
Lastly, when I put some data entry into the EXECUTE stored procedure and I got this error messages.
Msg 8146, Level 16, State 1, Procedure InsertCustomers_Cursor, Line 0 [Batch Start Line 40]
Procedure InsertCustomers_Cursor has no parameters and arguments were supplied.
Code:
create table customer
(
cust_id int primary key,
name varchar(100),
country varchar(50)
);
insert into customer
values (1, 'John Hammond', 'United States'),
(2, 'Mudassar Khan', 'India'),
(3, 'Robert Tan', 'Singapore'),
(4, 'Dennis Rodman', 'Indonesia'),
(5, 'Michelle Chia', 'Indonesia'),
(6, null, null);
select *
from customer;
CREATE PROCEDURE InsertCustomers_Cursor
AS
BEGIN
DECLARE #cust_id int,
#name varchar(100),
#country varchar(50)
DECLARE #Counter INT
SET #Counter = 1
DECLARE #AllRecords TABLE
(
cust_id int,
name varchar(100),
country varchar(50)
)
DECLARE InsertCustomers CURSOR READ_ONLY
FOR
SELECT cust_id, name, country
FROM customer
OPEN InsertCustomers
FETCH NEXT FROM InsertCustomers INTO #cust_id, #name, #country
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO #AllRecords
VALUES (#cust_id, #name, #country)
FETCH NEXT FROM InsertCustomers INTO #cust_id, #name, #country
END
CLOSE InsertCustomers
DEALLOCATE InsertCustomers
END
GO
-- This EXEC statement cannot run the query
EXEC InsertCustomers_Cursor 7, 'Michael Labone', Indonesia
-- This EXEC statement can run the query and the results is to show how many are being affected
EXEC InsertCustomers
The issue is your SP doesn't expect any parameter and you are calling it passing parameters
EXEC InsertCustomers_Cursor 7, 'Michael Labone', Indonesia
To make it works properly, you need to create these parameters in the SP:
CREATE PROCEDURE InsertCustomers_Cursor
#cust_id int,
#name varchar(100),
#country varchar(50)
AS
BEGIN
...
And remove this part:
DECLARE #cust_id int,
#name varchar(100),
#country varchar(50)
There could be more elegant ways to declare these parameters but for the example I think it's enough.
Related
I tried to make a stored procedure the insert data to a table:
create procedure AddEmployee
(
#FirstName nvarchar(20)
, #LastName nvarchar(20)
, #BirthDate datetime
, #Country nvarchar(15)
, #City nvarchar(15)
)
as
insert into Employees
values (#FirstName, #LastName, #BirthDate, #Country, #City)
go
But when I run it I get the error message:
Msg 213, Level 16, State 1, Procedure AddEmployee, Line 2 [Batch Start Line 17]
Column name or number of supplied values does not match table definition.
I looked at this question but it didn't solve my problem:
Create a stored procedure to insert new data into a table
When using insert, always include the columns names:
create procedure AddEmployee (
#FirstName nvarchar(20) ,
#LastName nvarchar(20) ,
#BirthDate datetime,
#Country nvarchar(15),
#City nvarchar(15)
) as
begin
insert into Employees (FirstName, LastName, BirthDate, Country, City)
values (#FirstName, #LastName, #BirthDate, #Country, #City);
end;
Although SQL allows you to leave out the column names, you should include them as a best-practice. This is particularly important for those learning the language, so they learn the safer way to do things.
I have a table Partners generated by
CREATE TABLE Partners (
id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID(),
name NVARCHAR(50) NOT NULL,
email NVARCHAR(254) NOT NULL, -- 254 is optimal length according to http://stackoverflow.com/questions/1199190/what-is-the-optimal-length-for-an-email-address-in-a-database
PRIMARY KEY (id)
);
and a attempt at a sproc for inserting a row and retrieving the id of the inserted row:
CREATE PROCEDURE AddPartner
#name NVARCHAR(50), #email NVARCHAR(254)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO Partners (name,email)
OUTPUT INSERTED.id INTO #new_guid
VALUES (#name,#email)
SELECT #new_guid
END
Suppose I want to (1) call AddPartner with (name,email) equal ('some dude','dude192#gmail.com) and return the id (call it dude_id) so that I can later (2) use it when I insert another row:
INSERT INTO Answers (question_id,partner_id,val) VALUES (1,dude_id,24);
How exactly can I do that? And will having GO statements between (1) and (2) ruin everything?
Add Output Parameter to your procedure
CREATE PROCEDURE Addpartner (#name NVARCHAR(50),
#email NVARCHAR(254),
#new_guid UNIQUEIDENTIFIER output)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO Partners
(name,email)
OUTPUT INSERTED.id INTO #new_guid
VALUES (#name,#email)
END
DECLARE #new_guid AS UNIQUEIDENTIFIER
EXEC Addpartner 'some dude', 'dude192#gmail.com', #new_guid output
INSERT INTO Answers
(question_id,partner_id,val)
VALUES (#output_identity,'dude_id',24);
I have a dynamic stored procedure that I run in Access 2013 by passing various parameters to it.
However, I need to now run the dynamic stored procedure in another Stored Procedure.
Currently I know how to Execute a standard stored procedure.
This is my dynamic stored procedure Execute that I use in another SP Called SP_ACTIVITY:
EXEC sp_executesql #sql, N'#ORGCODE VARCHAR(6), #COMPANYID VARCHAR(6)'
#ORGCODE, #COMPANYID;
Here is my code so far:
CREATE PROCEDURE [dbo].[ASP_SLACTIVITYPAGE]
#ORGCODE2 AS VARCHAR(6),
#COMPANYID2 AS VARCHAR(6)
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT 1 FROM tempdb..sysobjects
WHERE NAME = '#TempACTIVITY' and TYPE = 'U')
DROP TABLE #TempACTIVITY
CREATE TABLE #tempACTIVITY
(
CompanyID VARCHAR(6),
CompanyName VARCHAR(50),
PostingID INT,
EntryDate SmallDateTime,
TransType VARCHAR(2),
Ref VARCHAR(50),
Nominal INT,
Details VARCHAR(50),
SumofNetAmt DECIMAL(12,2),
SumofVATAmt DECIMAL(12,2),
SumofPaidAmt DECIMAL(12,2),
CustomerOrderNr VARCHAR(25),
WONUmber INT,
PaidStatus VARCHAR(2),
Credit DECIMAL(12,2),
Debit DECIMAL(12,2),
OutStanding DECIMAL(12,2)
);
GO
INSERT INTO #tempACTIVITY
(
CompanyID,
CompanyName,
PostingID,
EntryDate,
TransType,
Ref,
Nominal,
Details,
SumofNetAmt,
SumofVATAmt,
SumofPaidAmt,
CustomerOrderNr,
WONUmber,
PaidStatus,
Credit,
Debit,
OutStanding
)
EXEC sp_executesql SP_ACTVIITY, #ORGCODE2, #COMPANYID2 <----
---I want to execute with dynamic SP with parameters like the the one above.
I was quoting the Stored Procedure incorrectly.
The answer is:
EXEC [PROCNAME] #Param1, #Param2
I'm working on a cascading insertion where a stored procedure should return an id of the inserted row. This would not be a problem if the id of the table was an int. However, the id is a varchar and therefore I cannot use SCOPE_IDENTITY().
This is my procedure so far:
CREATE PROCEDURE NEW_ARTICLE
#id varchar(50) OUTPUT,
#name varchar(100),
#articleNr varchar(50),
#gategory varchar(50),
#containerId varchar(50),
#contPerContainer int,
#pictureId varchar(50)
AS
SET NOCOUNT OFF
INSERT INTO nextlabel.[Article] (name, article_nr, category, container_id, count_per_container, picture_id )
VALUES (#name, #articleNr, #gategory, #containerId, #contPerContainer, #pictureId)
SET #id = SCOPE_IDENTITY()
Where the last row is not correct since the column id is a varchar.
How can I return the id?
Try this:
CREATE PROCEDURE NEW_ARTICLE
#id varchar(50) OUTPUT,
#name varchar(100),
#articleNr varchar(50),
#gategory varchar(50),
#containerId varchar(50),
#contPerContainer int,
#pictureId varchar(50)
AS
SET NOCOUNT OFF
SET #id = newid()
INSERT INTO nextlabel.[Article] (id, name, article_nr, category, container_id, count_per_container, picture_id)
VALUES (#id, #name, #articleNr, #gategory, #containerId, #contPerContainer, #pictureId)
GO
I have 3 insert stored procedures each SP inserts data in 2 different tables
Table 1 Table 2
idPerson idProduct
name productName
phoneNumber productdescription
FK-idProduct
SP for table 1 SP for table 2
create procedure test1 create procedure test2
WITH WITH
EXECUTE as caller EXECUTE as caller
AS AS
declare declare
#idPerson int, #idProduct int,
#name varchar(20), #productName varchar(50),
#phone varchar(20) #productoDescription varchar(50)
SET nocount on; SET nocount on;
Begin Begin
insert into table1( insert into table2(
idPerson, idProduct,
name, productName,
phone) productDescription)
values( values(
#idPerson, #idProduct,
#name, #productName,
#phone) #productDescription)
end end
I need to call stored procedure test 2 from stored procedure test 1 and insert the FK-ID in the table 1
Simply call test2 from test1 like:
EXEC test2 #newId, #prod, #desc;
Make sure to get #id using SCOPE_IDENTITY(), which gets the last identity value inserted into an identity column in the same scope:
SELECT #newId = SCOPE_IDENTITY()
You could add an OUTPUT parameter to test2, and set it to the new id straight after the INSERT using:
SELECT #NewIdOutputParam = SCOPE_IDENTITY()
Then in test1, retrieve it like so:
DECLARE #NewId INTEGER
EXECUTE test2 #NewId OUTPUT
-- Now use #NewId as needed
First of all, if table2's idProduct is an identity, you cannot insert it explicitly until you set IDENTITY_INSERT on that table
SET IDENTITY_INSERT table2 ON;
before the insert.
So one of two, you modify your second stored and call it with only the parameters productName and productDescription and then get the new ID
EXEC test2 'productName', 'productDescription'
SET #newID = SCOPE_IDENTIY()
or you already have the ID of the product and you don't need to call SCOPE_IDENTITY() and can make the insert on table1 with that ID