Asked by:
how to insert single row in Order table and multiple rows in OrderDetails table via stored procedure.

-
text/html 6/21/2013 1:48:07 PM rasol 0
Thank you For Help
Let Me ExplainBetter .
I have four tables Named Customers_0, Orders_0, Order_Details and Products That Their Characteristics Are As Follows :
Customers_0
Column Name
Data Type
Allow Null
Cust_id
int
Unchecked
Name
nvarchar(30)
Unchecked
Family
nvarchar(30)
Unchecked
Phone
nvarchar(20)
Unchecked
Address
nvarchar(50)
Unchecked
Cust_id is PK and identity (1,1)
Orders_0
Column Name
Data Type
Allow Null
Ord_id
int
Unchecked
Ord_date
nchar(20)
Unchecked
Cust_id
int
Checked
Ord_id is PK and identity(1,1) ; Cust_id is FK .
There are 1-to-M Relationship BetweenCustomers_0 and Orders_0 .
Order_Details
Column Name
Data Type
Allow Null
Prod_id
int
Unchecked
Prod_name
nvarchar(50)
Unchecked
Quantity
numeric(18, 0)
Unchecked
Fee
money
Unchecked
Total_Amount
money
Unchecked
Unit
nchar(20)
Unchecked
Ord_id
int
Checked
Prod_id is PK and Not Identity ; Ord_id is FK .
There are 1-to-M Relationship BetweenOrders_0 and Order_Details .
I want insert single row in Order table and multiple rows in OrderDetails table via stored procedure.
Please hlpe me!
Please Give Me A Stored Procedure And A Algorithm Of This Sample.
Question
All replies
-
text/html 6/21/2013 2:58:45 PM Geert Vanhove DCOD 0
Step 1: insert into Orders table
Step 2: capture the identity value generated by the system using SCOPE_IDENTITY()
Step 3: insert into OrderDetails table using the results of the SCOPE_IDENTITY() value as FK
Geert Vanhove DCOD ------ http://geertvanhove.wordpress.com/ ----------- Please click the Mark as Answer or Vote As Helpful if a post solves your problem or is helpful!
-
text/html 6/22/2013 5:52:54 AM Fanny Liu 0
Hello,
Just as Geert post above, you can use the SCOPE_IDENTITY() to get the last value for Ord_id in the Orders table and pass to the value into OrderDetails table.
Please refer to the sample Stored Procedure as Uri post in the following thread:
http://social.technet.microsoft.com/Forums/en-US/e5e78bf5-5420-4e58-bb7d-da466a5ba47f/how-to-insert-multiple-rows-in-multiple-tables-sql-2005Fanny Liu
TechNet Community Support -
text/sourcefragment 6/22/2013 3:58:20 PM Tom Groszko 1
USE tempdb; go --DROP TABLE dbo.OrderDetail; --DROP TABLE dbo.Product; --DROP TABLE dbo.OrderHeader; --DROP TABLE dbo.Customer; --DROP PROCEDURE dbo.InsertOrder; --DROP TYPE dbo.OrderDetailInput; GO CREATE TABLE dbo.Customer ( Cust_id BIGINT PRIMARY KEY IDENTITY(-9223372036854775808, 1) NOT NULL ,Name NVARCHAR(30) UNIQUE NOT NULL ,Family NVARCHAR(30) NULL ,Phone NVARCHAR(30) NULL ,Address NVARCHAR(30) NULL ); CREATE TABLE dbo.OrderHeader ( Ord_id BIGINT PRIMARY KEY IDENTITY(-9223372036854775808, 1) NOT NULL ,Ord_date DATE NOT NULL ,Cust_id BIGINT NOT NULL ,CONSTRAINT FK_Customer FOREIGN KEY(Cust_id) REFERENCES dbo.Customer (Cust_id) ); CREATE TABLE dbo.Product ( Prod_id BIGINT PRIMARY KEY IDENTITY(-9223372036854775808, 1) NOT NULL ,Prod_Name NVARCHAR(255) UNIQUE NOT NULL ); CREATE TABLE dbo.OrderDetail ( Ord_id BIGINT NOT NULL ,Detail_id BIGINT PRIMARY KEY IDENTITY(-9223372036854775808, 1) NOT NULL ,Prod_ID BIGINT ,Quantity INT ,Fee money ,Total_Amount as Quantity * Fee ,CONSTRAINT FK_OrderHeader FOREIGN KEY(Ord_id) REFERENCES dbo.OrderHeader (Ord_id) ,CONSTRAINT FK_Product FOREIGN KEY(Prod_ID) REFERENCES dbo.Product (Prod_ID) ); CREATE TYPE dbo.OrderDetailInput as TABLE ( Prod_Name NVARCHAR(255) NOT NULL ,Quantity INT NOT NULL ,Fee MONEY NOT NULL ) IF (OBJECT_ID('dbo.InsertOrder', 'P ') IS NULL) BEGIN; EXEC('CREATE PROCEDURE dbo.InsertOrder AS SELECT ''This should be replaced''') END; GO ALTER PROCEDURE dbo.InsertOrder @OrderDate DATE ,@Cust_Name NVARCHAR(30) ,@OrderDetail dbo.OrderDetailInput readonly AS SET NOCOUNT ON; DECLARE @ReturnCode INT = 0; DECLARE @OrderHeaderID BIGINT; BEGIN TRY INSERT INTO dbo.OrderHeader ( Ord_date ,Cust_id ) SELECT @OrderDate ,Cust_id FROM dbo.Customer Customer WHERE Customer.Name = @Cust_Name; SELECT @OrderHeaderID = SCOPE_IDENTITY(); INSERT INTO dbo.OrderDetail ( Ord_id ,Prod_ID ,Quantity ,Fee ) SELECT @OrderHeaderID ,Product.Prod_id ,OrderDetail.Quantity ,OrderDetail.Fee FROM @OrderDetail OrderDetail JOIN dbo.Product Product on OrderDetail.Prod_Name = Product.Prod_Name; END TRY BEGIN CATCH IF (XACT_STATE() <> 0) -- 1 OR -1 says there is an active transaction. BEGIN ROLLBACK TRANSACTION; END; DECLARE @OOPSMessage VARCHAR(MAX); SELECT @OOPSMessage = 'ERROR_PROCEDURE (' + ERROR_PROCEDURE() + ')' + CHAR(10) + ', ERROR_LINE (' + CAST(ERROR_LINE() AS VARCHAR(25)) + ')' + CHAR(10) + ', ERROR_NUMBER (' + CAST(ERROR_NUMBER() AS VARCHAR(25)) + ')' + CHAR(10) + ', ERROR_SEVERITY (' + CAST(ERROR_SEVERITY() AS VARCHAR(25)) + ')' + CHAR(10) + ', ERROR_STATE (' + CAST(ERROR_STATE() AS VARCHAR(25)) + ')' + CHAR(10) + ', ERROR_MESSAGE (' + ERROR_MESSAGE() + ')'; RAISERROR (@OOPSMessage, 11, 10) WITH LOG; SELECT @ReturnCode = -1; END CATCH; RETURN @ReturnCode; GO INSERT INTO dbo.Customer ( Name ,Family ,Phone ,Address ) VALUES ( N'Sam Adams', N'Adams Family', N'Adams Phone', N'Adams Address') ,( N'Sam Smith', N'Smith Family', N'Smith Phone', N'Smith Address'); SELECT * FROM dbo.Customer; INSERT INTO dbo.Product ( Prod_Name ) VALUES (N'Big Apple') ,(N'Small Apple') ,(N'Strawberry'); SELECT * FROM dbo.Product; DECLARE @NewOrderDetail dbo.OrderDetailInput; Insert @NewOrderDetail ( Prod_Name ,Quantity ,Fee ) values (N'Big Apple', 1, $1.23) ,(N'Small Apple', 10, $10.23) ,(N'Strawberry', 25, $22.23); EXEC dbo.InsertOrder '2013-06-21' ,N'Sam Adams' ,@NewOrderDetail SELECT * FROM dbo.OrderHeader SELECT * FROM dbo.OrderDetail
This should be close to what you need.Tom G.
-
text/html 6/22/2013 5:56:03 PM --CELKO-- 0Please post DDL, so that people do not have to guess what the keys, constraints, Declarative Referential Integrity, data types, etc. in your schema are. Learn how to follow ISO-11179 data element naming conventions and formatting rules (you failed). Temporal data should use ISO-8601 formats. Code should be in Standard SQL as much as possible and not local dialect.
This is minimal polite behavior on SQL forums. What you did post is useless and needs to be corrected. For example, no competent data modeler would use INTEGER for a customer_id, MONEY is proprietary and does not do correct math (Google it!), you do knwo the length of a phone number (E.123 Standard)
I have four tables Named Customers, Orders, Order_Details and Products That Their Characteristics Are As Follows :
CREATE TABLE Customers
(cust_id CHAR(16) NOT NULL PRIMARY KEY, -- size of credit card #
cust_first_name VARCHAR(20) NOT NULL,
cust_last_name VARCHAR(20) NOT NULL,
cust_phone NOT NULL CHAR(18) NOT NULL,
san CHAR(10) NOT NULL);
An address of VARCHAR(50) is wrong; each line ion a USPS address is VARCHAR(35) and there are five of them. However, serious databases have a SAN (Standard Address Number). This gives you the full streeet address.
>> cust_id is PK and IDENTITY (1,1) <<
You have never read a book or had a course on RDBMS; why do you think the count of physical insertion attempts to one file on one disk drive is an attribute of customer?? How do you verify and validate this magical Kabbalah number?
CREATE TABLE Orders
(order_nbr CHAR(10) NOT NULL PRIMARY KEY,
order_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL,
cust_id CHAR(10) NOT NULL
REFERENCES Customers(cust_id)
ON DELETE CASCADE
ON UPDATE CASCADE);
Again, no competent SQL programmer would use IDENTITY(1,1). The use of strings for a date is dangerous, insanely slow and stupid.
CREATE TABLE Order_Details
(order_nbr CHAR(10) NOT NULL
REFERENCES Orders(order_nbr)
ON DELETE CASCADE
ON UPDATE CASCADE,
product_gtin CHAR(15) NOT NULL
REFERENCES Inventory (product_gtin),
order_qty INTEGER NOT NULL);
Products are identified by some industry standard. The GTIN is the most general, so I will use it. The product name should not be here; you have the GTIN and you find the product name in Inventory. You will get the unit price, product name, and other data from the3 Inventory; it will not be in the order details. Likewise, we do not keep redundant data like a total amount. The term “fee” makes no sense in this context. We need the quantity and unit price for an order item.
Do you know about normalization? You need to learn.
>> please give me a stored procedure and an algorithm <<
This smells like a homework assignment. We will need to check and report you for cheating, if so. The worst way would be to use SCOPE_IDENTITY() and keep the non-RDBMS disaster you have in your non_DDL ASCII pictures.
Here is a skeleton that you can research. It uses the long parameter list SQL idiom. You will probably need to research it, since you did not know normalization.
CREATE PROCEDURE Place_Order
(@in_cust_id CHAR(16),
@in_order_nbr CHAR(10),
@in_order_date = CURRENT_TIMESTAMP,
@in_product_gtin_1 = NULL,
@in_order_qty_1 = NULL,
…
@in_product_gtin_n = NULL,
@in_order_qty_n = NULL)
BEGIN
INSERT INTO Orders
VALUES (@in_order_nbr, @in_order_date, @in_cust_id);
INSERT INTO Order_Details
SELECT @in_order_nbr, X.product_gtin, X.order_qty
FROM (VALUES (@in_product_gtin_1, @in_order_qty_1),
(@in_product_gtin_2, @in_order_qty_2),
...
(@in_product_gtin_n, @in_order_qty_n)) AS X
WHERE X.product_gtin IS NOT NULL;
END;
You will need to add error handling, validations and other things to make it a real proc.--CELKO-- Books in Celko Series for Morgan-Kaufmann Publishing: Analytics and OLAP in SQL / Data and Databases: Concepts in Practice Data / Measurements and Standards in SQL SQL for Smarties / SQL Programming Style / SQL Puzzles and Answers / Thinking in Sets / Trees and Hierarchies in SQL
-
text/html 6/26/2013 9:29:16 AM rasol 0
thank you for help dear Tom G.
how i can call and execute this table_valued stored procedure in vb.net 2010
USE tempdb;
go
--DROP TABLE dbo.OrderDetail;
--DROP TABLE dbo.Product;
--DROP TABLE dbo.OrderHeader;
--DROP TABLE dbo.Customer;
--DROP PROCEDURE dbo.InsertOrder;
--DROP TYPE dbo.OrderDetailInput;
GO
CREATE TABLE dbo.Customer
( Cust_id BIGINT PRIMARY KEY IDENTITY(-9223372036854775808, 1) NOT NULL
,Name NVARCHAR(30) UNIQUE NOT NULL
,Family NVARCHAR(30) NULL
,Phone NVARCHAR(30) NULL
,Address NVARCHAR(30) NULL
);
CREATE TABLE dbo.OrderHeader
( Ord_id BIGINT PRIMARY KEY IDENTITY(-9223372036854775808, 1) NOT NULL
,Ord_date DATE NOT NULL
,Cust_id BIGINT NOT NULL
,CONSTRAINT FK_Customer FOREIGN KEY(Cust_id)
REFERENCES dbo.Customer (Cust_id)
);
CREATE TABLE dbo.Product
( Prod_id BIGINT PRIMARY KEY IDENTITY(-9223372036854775808, 1) NOT NULL
,Prod_Name NVARCHAR(255) UNIQUE NOT NULL
);
CREATE TABLE dbo.OrderDetail
( Ord_id BIGINT NOT NULL
,Detail_id BIGINT PRIMARY KEY IDENTITY(-9223372036854775808, 1) NOT NULL
,Prod_ID BIGINT
,Quantity INT
,Fee money
,Total_Amount as Quantity * Fee
,CONSTRAINT FK_OrderHeader FOREIGN KEY(Ord_id)
REFERENCES dbo.OrderHeader (Ord_id)
,CONSTRAINT FK_Product FOREIGN KEY(Prod_ID)
REFERENCES dbo.Product (Prod_ID)
);
CREATE TYPE dbo.OrderDetailInput as TABLE
( Prod_Name NVARCHAR(255) NOT NULL
,Quantity INT NOT NULL
,Fee MONEY NOT NULL
)
IF (OBJECT_ID('dbo.InsertOrder', 'P ') IS NULL)
BEGIN; EXEC('CREATE PROCEDURE dbo.InsertOrder AS SELECT ''This should be replaced''')
END;
GO
ALTER PROCEDURE dbo.InsertOrder
@OrderDate DATE
,@Cust_Name NVARCHAR(30)
,@OrderDetail dbo.OrderDetailInput readonly
AS
SET NOCOUNT ON;
DECLARE @ReturnCode INT = 0;
DECLARE @OrderHeaderID BIGINT;
BEGIN TRY
INSERT INTO dbo.OrderHeader
( Ord_date
,Cust_id
)
SELECT @OrderDate
,Cust_id
FROM dbo.Customer Customer
WHERE Customer.Name = @Cust_Name;
SELECT @OrderHeaderID = SCOPE_IDENTITY();
INSERT INTO dbo.OrderDetail
( Ord_id
,Prod_ID
,Quantity
,Fee
)
SELECT @OrderHeaderID
,Product.Prod_id
,OrderDetail.Quantity
,OrderDetail.Fee
FROM @OrderDetail OrderDetail
JOIN dbo.Product Product on OrderDetail.Prod_Name = Product.Prod_Name;
END TRY
BEGIN CATCH IF (XACT_STATE() <> 0) -- 1 OR -1 says there is an active transaction.
BEGIN ROLLBACK TRANSACTION;
END;
DECLARE @OOPSMessage VARCHAR(MAX);
SELECT @OOPSMessage = 'ERROR_PROCEDURE (' + ERROR_PROCEDURE()
+ ')' + CHAR(10) + ', ERROR_LINE (' + CAST(ERROR_LINE() AS VARCHAR(25))
+ ')' + CHAR(10) + ', ERROR_NUMBER (' + CAST(ERROR_NUMBER() AS VARCHAR(25))
+ ')' + CHAR(10) + ', ERROR_SEVERITY (' + CAST(ERROR_SEVERITY() AS VARCHAR(25))
+ ')' + CHAR(10) + ', ERROR_STATE (' + CAST(ERROR_STATE() AS VARCHAR(25))
+ ')' + CHAR(10) + ', ERROR_MESSAGE (' + ERROR_MESSAGE()
+ ')';
RAISERROR (@OOPSMessage, 11, 10) WITH LOG;
SELECT @ReturnCode = -1;
END CATCH;
RETURN @ReturnCode;
GO
INSERT INTO dbo.Customer
( Name
,Family
,Phone
,Address
) VALUES
( N'Sam Adams', N'Adams Family', N'Adams Phone', N'Adams Address')
,( N'Sam Smith', N'Smith Family', N'Smith Phone', N'Smith Address');
SELECT *
FROM dbo.Customer;
INSERT INTO dbo.Product
( Prod_Name
) VALUES
(N'Big Apple')
,(N'Small Apple')
,(N'Strawberry');
SELECT *
FROM dbo.Product;
DECLARE @NewOrderDetail dbo.OrderDetailInput;
Insert @NewOrderDetail
( Prod_Name
,Quantity
,Fee
) values
(N'Big Apple', 1, $1.23)
,(N'Small Apple', 10, $10.23)
,(N'Strawberry', 25, $22.23);
EXEC dbo.InsertOrder
'2013-06-21'
,N'Sam Adams'
,@NewOrderDetail
SELECT *
FROM dbo.OrderHeader
SELECT *
FROM dbo.OrderDetail -
text/html 6/26/2013 12:35:36 PM Tom Groszko 0
-
text/html 8/5/2013 8:46:13 AM rasol 0