Right now I am using 3 stored procedures to Add a person to the person.person table. I would like to cut this down to a single stored procedure to resolve this issue.
INSERT new GUID and DateModified to table Person.BusinessEntity
SELECT the auto generate BusinessEntityID form table Person.BusinessEntity
INSERT new Person to Person.Person Table
The Stored Procedures all use parameters which I pass via a C# application and I have confirmed that the a user is in fact added to the AdventureWorks2019 Db.
Procedure: Person.CreateNewBusinessEntity
INSERT INTO [Person].[BusinessEntity]
(
[BusinessEntity].rowguid
, [BusinessEntity].ModifiedDate
)
VALUES
(
#RowGUID
, GetDate()
)
Procedure: Person.GetBusinessEntityID
SELECT
[BusinessEntityID]
FROM
[AdventureWorks2019].[Person].[BusinessEntity]
WHERE [rowguid] = #RowGuid
Procedure: Person.CreateNewPerson
INSERT INTO [Person].[Person]
(
[BusinessEntityID]
,[PersonType]
,[NameStyle]
,[Title]
,[FirstName]
,[MiddleName]
,[LastName]
,[Suffix]
,[EmailPromotion]
,[AdditionalContactInfo]
,[Demographics]
,[rowguid]
,[ModifiedDate]
)
VALUES
(
#BusinessEntityID
, #PersonType
, #NameStyle
, #Title
, #FirstName
, #MiddleName
, #LastName
, #Suffix
, #EmailPromotion
, #AdditionalContactInfo
, #Demographics
, #RowGUID
, GetDate()
)
Any help here is appreciated. Thanks!
Thanks to HABO, I am now using this solution. Now I only need two procedures.
DECLARE #Inserted table ( [BusinessEntityID] int );
INSERT INTO [Person].[BusinessEntity]
(
[BusinessEntity].rowguid
, [BusinessEntity].ModifiedDate
)
OUTPUT inserted.[BusinessEntityID] INTO #Inserted([BusinessEntityID])
VALUES
(
#RowGUID
, GetDate()
)
The below answer shows you how to get the inserted id and add it to the next insert in side the Same SP.
USE AdventureWorks2012
GO
CREATE PROC CreateNewPerson
AS
BEGIN
DECLARE #OutputTbl TABLE ([BusinessEntityID] INT, ModifiedDate DATETIME)
DECLARE #BusinessEntityID AS INT
INSERT INTO [Person].[BusinessEntity]
(
[BusinessEntity].rowguid
, [BusinessEntity].ModifiedDate
)
--Get the output value inserted to a table.
OUTPUT inserted.[BusinessEntityID], inserted.ModifiedDate INTO
#OutputTbl([BusinessEntityID],[ModifiedDate])
VALUES
(
NEWID()
, GetDate()
)
--Assigned to a variable. You can get this using subquery as well inside the insert statment.
SELECT #BusinessEntityID = [BusinessEntityID] FROM #OutputTbl
INSERT INTO [Person].[Person]
(
[BusinessEntityID]
,[PersonType]
,[NameStyle]
,[Title]
,[FirstName]
,[MiddleName]
,[LastName]
,[Suffix]
,[EmailPromotion]
,[AdditionalContactInfo]
,[Demographics]
,[rowguid]
,[ModifiedDate]
)
VALUES
(
#BusinessEntityID
, #PersonType --These columns with # sign needed to be declared or supply values
, #NameStyle
, #Title
, #FirstName
, #MiddleName
, #LastName
, #Suffix
, #EmailPromotion
, #AdditionalContactInfo
, #Demographics
, NEWID() --This will generate a new GUID for each row.
, GetDate()
)
END
GO
Second way is using Scope_identity(). Replace the
"SELECT #BusinessEntityID = [BusinessEntityID] FROM #OutputTbl'
from below lines in the Sp will do the same thing for you.
SELECT #BusinessEntityID = SCOPE_IDENTITY() --[BusinessEntityID] FROM #OutputTbl
Select #BusinessEntityID
Related
This sample XML shown here is what I want to import into a SQL Server table. The XML tags are dynamic here.( xml element name differ in othe xml files. Also number of xml elements in root and child nodes are different for each xml file)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:heal="http://healthedge.com">
<soapenv:Header/>
<soapenv:Body>
<heal:getClaimDetailsByHccID>
<claimHccNumber>10</claimHccNumber>
<claimDetailFlags>
<includeAccounts>a</includeAccounts>
<includeAccumulators>b</includeAccumulators>
</claimDetailFlags>
<claimFilterParameters>
<includeTransientStates>true</includeTransientStates>
<mostRecentPaymentOnly>false</mostRecentPaymentOnly>
</claimFilterParameters>
</heal:getClaimDetailsByHccID>
</soapenv:Body>
</soapenv:Envelope>
I want to store xml into 3 different tables, one table for each level element(root,child, sub child) the tag names are stored as row data.
Output should look like this:
Parent table
id value
---------------------------
1 getClaimDetailsByHccID
Root table
parent_id root id name value
------------------------------------------------------
1 1 claimHccNumber 10
1 2 claimDetailFlags null
1 3 claimFilterParameters null
Child table
root id child id name value
--------------------------------------------------------
2 1 includeAccounts a
2 2 includeAccumulators b
3 3 includeTransientStates TRUE
3 4 mostRecentPaymentOnly FALSE
i tried using below code, here value is not populating correctly for rootTable code:-
DROP TABLE IF EXISTS ChildTbl;
DROP TABLE IF EXISTS RootTbl;
DROP TABLE IF EXISTS ParentTbl;
CREATE TABLE ParentTbl (ID INT IDENTITY PRIMARY KEY, [value] VARCHAR(100));
CREATE TABLE RootTbl (root_id INT IDENTITY PRIMARY KEY, parent_id INT, [name] VARCHAR(100), [value] VARCHAR(100));
CREATE TABLE ChildTbl (child_id INT IDENTITY PRIMARY KEY, parent_id INT, [name] VARCHAR(100), [value] VARCHAR(100));
DECLARE #xml XML = N'
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:heal="http://healthedge.com">
<soapenv:Header/>
<soapenv:Body>
<heal:getClaimDetailsByHccID>
<claimHccNumber>10</claimHccNumber>
<claimDetailFlags>
<includeAccounts>a</includeAccounts>
<includeAccumulators>b</includeAccumulators>
</claimDetailFlags>
<claimFilterParameters>
<includeTransientStates>true</includeTransientStates>
<mostRecentPaymentOnly>false</mostRecentPaymentOnly>
</claimFilterParameters>
</heal:getClaimDetailsByHccID>
</soapenv:Body>
</soapenv:Envelope>'
-- DDL and sample data population, end
DECLARE #ParentID INT
, #RootID INT;
-- Parent table handling
-- =========================================================================
;WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS soapenv
, 'http://healthedge.com' AS heal), rs AS
(
SELECT c.value('local-name(heal:*[1])','VARCHAR(100)') AS [value]
FROM #xml.nodes('/soapenv:Envelope/soapenv:Body') AS t(c)
)
INSERT INTO dbo.ParentTbl (value)
SELECT * FROM rs;
SET #ParentID = SCOPE_IDENTITY();
-- RootTbl table handling
-- =========================================================================
;WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS soapenv
, 'http://healthedge.com' AS heal), rs AS
(
SELECT c.value('local-name(.)','VARCHAR(100)') AS [name]
, c.value('(*[1]/text())[1]','VARCHAR(100)') AS [value]
-- ,c.value('./.','VARCHAR(100)') AS [value1]
FROM #xml.nodes('/*/*/*/*') AS t(c)
)
INSERT INTO dbo.RootTbl (parent_id, [name], [value])
SELECT #ParentID, * FROM rs;
SET #RootID = SCOPE_IDENTITY();
----child----
;WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS soapenv
, 'http://healthedge.com' AS heal), rs AS
(
SELECT c.value('local-name(.)','VARCHAR(100)') AS [name]
, c.value('./.','VARCHAR(100)') AS [value]
FROM #xml.nodes('/*/*/*/*/*') AS t(c)
)
INSERT INTO dbo.ChildTbl (parent_id, [name], [value])
SELECT #RootID, * FROM rs;
-- test
SELECT * FROM dbo.ParentTbl;
SELECT * FROM dbo.RootTbl
SELECT * FROM dbo.ChildTbl;
It is not so clear what it means "...The XML tags are dynamic here...".
Please try the following solution.
USE tempdb;
GO
-- DDL and sample data population, start
DROP TABLE IF EXISTS dbo.ChildTbl;
DROP TABLE IF EXISTS dbo.RootTbl;
DROP TABLE IF EXISTS dbo.ParentTbl;
CREATE TABLE dbo.ParentTbl (ID INT IDENTITY PRIMARY KEY, [value] VARCHAR(100));
CREATE TABLE dbo.RootTbl (root_id INT IDENTITY PRIMARY KEY
, parent_id INT NOT NULL FOREIGN KEY REFERENCES dbo.ParentTbl(ID), [name] VARCHAR(100), [value] VARCHAR(100));
CREATE TABLE dbo.ChildTbl (child_id INT IDENTITY PRIMARY KEY
, parent_id INT NOT NULL FOREIGN KEY REFERENCES dbo.RootTbl(root_id), [name] VARCHAR(100), [value] VARCHAR(100));
/*
DECLARE #xml XML = N'
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:heal="http://healthedge.com">
<soapenv:Header/>
<soapenv:Body>
<heal:getClaimDetailsByHccID>
<claimHccNumber>10</claimHccNumber>
<claimDetailFlags>
<includeAccounts>a</includeAccounts>
<includeAccumulators>b</includeAccumulators>
</claimDetailFlags>
<claimFilterParameters>
<includeTransientStates>true</includeTransientStates>
<mostRecentPaymentOnly>false</mostRecentPaymentOnly>
</claimFilterParameters>
</heal:getClaimDetailsByHccID>
</soapenv:Body>
</soapenv:Envelope>';
*/
DECLARE #xml XML = N'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:heal="http://healthedge.com">
<soapenv:Header/>
<soapenv:Body>
<heal:getClaimDetailsByHccID>
<claimHccNumber>10</claimHccNumber>
<claimDetailFlags>
<includeAccounts>1</includeAccounts>
<includeAccumulators>2</includeAccumulators>
<includeBenefitNetwork>3</includeBenefitNetwork>
<includeBenefitPlan>4</includeBenefitPlan>
<includeExternalRepricerResult>101</includeExternalRepricerResult>
<includeFundedAccounts>5</includeFundedAccounts>
<includeIngenixExternalLineResult>102</includeIngenixExternalLineResult>
<includePractitioner>6</includePractitioner>
<includeProcedureInformation>7</includeProcedureInformation>
<includeProduct>8</includeProduct>
<includeReportingCategories>9</includeReportingCategories>
<includeReportingCategoriesDescription>10</includeReportingCategoriesDescription>
<includeRepricerName>11</includeRepricerName>
<includeSupplier>12</includeSupplier>
<includeSupplierInvoice>13</includeSupplierInvoice>
<includeSupplierLocation>14</includeSupplierLocation>
<includeWithholding>15</includeWithholding>
</claimDetailFlags>
<claimFilterParameters>
<asOfDateTime>51</asOfDateTime>
<claimState>52</claimState>
<includeAllPreviouslyPaid>53</includeAllPreviouslyPaid>
<includeReversedClaimHeader>54</includeReversedClaimHeader>
<includeTransientStates>55</includeTransientStates>
<mostRecentPaymentOnly>56</mostRecentPaymentOnly>
<paymentBatchNumber>57</paymentBatchNumber>
<paymentDateRangeEnd>58</paymentDateRangeEnd>
<paymentDateRangeStart>59</paymentDateRangeStart>
<usePlanTypeFromClaimLine>60</usePlanTypeFromClaimLine>
</claimFilterParameters>
</heal:getClaimDetailsByHccID>
</soapenv:Body>
</soapenv:Envelope>';
-- DDL and sample data population, end
DECLARE #ParentID INT
, #RootID INT;
-- Parent table handling
-- =========================================================================
;WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS soapenv
, 'http://healthedge.com' AS heal), rs AS
(
SELECT c.value('local-name(heal:*[1])','VARCHAR(100)') AS [value]
FROM #xml.nodes('/soapenv:Envelope/soapenv:Body') AS t(c)
)
INSERT INTO dbo.ParentTbl (value)
SELECT * FROM rs;
SET #ParentID = SCOPE_IDENTITY();
-- RootTbl table handling
-- =========================================================================
;WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS soapenv
, 'http://healthedge.com' AS heal), rs AS
(
SELECT c.value('local-name(.)','VARCHAR(100)') AS [name]
, c.value('(./text())[1]','VARCHAR(100)') AS [value]
FROM #xml.nodes('/soapenv:Envelope/soapenv:Body/heal:getClaimDetailsByHccID/*[1]') AS t(c)
)
INSERT INTO dbo.RootTbl (parent_id, [name], [value])
SELECT #ParentID, * FROM rs;
-- claimDetailFlags handling
-- =========================================================================
;WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS soapenv
, 'http://healthedge.com' AS heal), rs AS
(
SELECT c.value('local-name(.)','VARCHAR(100)') AS [name]
, NULL AS [value]
FROM #xml.nodes('/soapenv:Envelope/soapenv:Body/heal:getClaimDetailsByHccID/claimDetailFlags') AS t(c)
)
INSERT INTO dbo.RootTbl (parent_id, [name], [value])
SELECT #ParentID, * FROM rs;
SET #RootID = SCOPE_IDENTITY();
-- ChildTbl handling
-- =========================================================================
;WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS soapenv
, 'http://healthedge.com' AS heal), rs AS
(
SELECT c.value('local-name(.)','VARCHAR(100)') AS [name]
, c.value('(./text())[1]','VARCHAR(100)') AS [value]
FROM #xml.nodes('/soapenv:Envelope/soapenv:Body/heal:getClaimDetailsByHccID/claimDetailFlags/*') AS t(c)
)
INSERT INTO dbo.ChildTbl (parent_id, [name], [value])
SELECT #RootID, * FROM rs;
-- claimFilterParameters handling
-- =========================================================================
;WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS soapenv
, 'http://healthedge.com' AS heal), rs AS
(
SELECT c.value('local-name(.)','VARCHAR(100)') AS [name]
, NULL AS [value]
FROM #xml.nodes('/soapenv:Envelope/soapenv:Body/heal:getClaimDetailsByHccID/claimFilterParameters') AS t(c)
)
INSERT INTO dbo.RootTbl (parent_id, [name], [value])
SELECT #ParentID, * FROM rs;
SET #RootID = SCOPE_IDENTITY();
-- ChildTbl handling
-- =========================================================================
;WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS soapenv
, 'http://healthedge.com' AS heal), rs AS
(
SELECT c.value('local-name(.)','VARCHAR(100)') AS [name]
, c.value('(./text())[1]','VARCHAR(100)') AS [value]
FROM #xml.nodes('/soapenv:Envelope/soapenv:Body/heal:getClaimDetailsByHccID/claimFilterParameters/*') AS t(c)
)
INSERT INTO dbo.ChildTbl (parent_id, [name], [value])
SELECT #RootID, * FROM rs;
-- test
SELECT * FROM dbo.ParentTbl;
SELECT * FROM dbo.RootTbl
SELECT * FROM dbo.ChildTbl;
I am trying to write a stored procedure which writes xml into a DB, T-SQL.
Here is my sample xml (which will have a significant number of <RECORD>s in prod environment):
<?xml version="1.0" encoding="windows-1251"?>
<DATA FORMAT_VERSION="1.0">
<RECORD>
<NAME>МІЖНАРОДНА ГРОМАДСЬКА ОРГАНІЗАЦІЯ МІЖНАРОДНА АКАДЕМІЯ БІОЕНЕРГОТЕХНОЛОГІЙ</NAME>
<SHORT_NAME>МАБЕТ</SHORT_NAME>
<EDRPOU>00011601</EDRPOU>
<ADDRESS>01001, м.Київ, Шевченківський район, ВУЛИЦЯ ПРОРІЗНА, будинок 8, офіс 426</ADDRESS>
<STAN>зареєстровано</STAN>
</RECORD>
</DATA>
I pass the path to the xml file in the #pathToXml parameter.
Here is my stored procedure:
CREATE PROCEDURE [dbo].[LegalContractorsDataSynchronize]
(
#pathToXml varchar
)
AS
BEGIN
BEGIN TRANSACTION
DELETE FROM [dbo].[LegalContractors];
INSERT INTO [dbo].[LegalContractors]([Code], [ShortName], [Name], [LegalAddress], [Status])
SELECT CONVERT([Code], [ShortName], [Name], [LegalAddress], [Status])
FROM OPENROWSET(BULK, #pathToXml, SINGLE_CLOB) as x
COMMIT TRANSACTION
END
I am using Entity Framework to call the stored procedure. The call just happens (with no errors), but the DB is not updated. I am very sure that I mistyped something in the INSERT statement. I followed this example.
Could someone point out how could I fill the three columns in my DB using the data from the respective elements in xml? The columns are Code, ShortName, Name, LegalAddress and Status.
UPDATE
After the answer being posted I tried the suggested solution. I am getting the error:
Msg 102, Level 15, State 1, Procedure LegalContractorsDataSynchronize, Line 15 [Batch Start Line 0]
Incorrect syntax near '#pathToXml'.
Here is my code:
CREATE PROCEDURE [dbo].[LegalContractorsDataSynchronize]
(
#pathToXml varchar
)
AS
BEGIN
BEGIN TRANSACTION
DELETE FROM [dbo].[LegalContractors];
;WITH XmlFile (xmlData) AS
(
SELECT TRY_CAST(BulkColumn AS XML)
FROM OPENROWSET(BULK #pathToXml, SINGLE_BLOB) AS x
)
INSERT INTO [dbo].[LegalContractors] ([Code], [ShortName], [Name], [LegalAddress], [Status])
SELECT c.value('(EDRPOU/text())[1]','NVARCHAR(100)') AS [Code]
, c.value('(SHORT_NAME/text())[1]','NVARCHAR(512)') AS [ShortName]
, c.value('(NAME/text())[1]','NVARCHAR(2048)') AS [Name]
, c.value('(ADDRESS/text())[1]','NVARCHAR(2048)') AS [LegalAddress]
, c.value('(STAN/text())[1]','NVARCHAR(100)') AS [Status]
FROM XmlFile CROSS APPLY xmlData.nodes('/DATA/RECORD') AS t(c);
COMMIT TRANSACTION
END
Please try the following. To the best of my knowledge, OPENROWSET() doesn't accept file name parameter as a variable.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (
ID INT IDENTITY PRIMARY KEY,
Code NVARCHAR(50) NOT NULL,
ShortName NVARCHAR(100) NOT NULL,
[Name] NVARCHAR(100) NOT NULL,
LegalAddress NVARCHAR(100) NOT NULL,
[Status] NVARCHAR(50) NOT NULL
);
-- DDL and sample data population, end
-- Method #1
-- XML file is hardcoded
;WITH XmlFile (xmlData) AS
(
SELECT TRY_CAST(BulkColumn AS XML)
FROM OPENROWSET(BULK 'c:\...\Ukraine.xml', /*CODEPAGE = '65001',*/ SINGLE_BLOB) AS x
)
INSERT INTO #tbl (Code, ShortName, [Name], LegalAddress, [Status])
SELECT c.value('(EDRPOU/text())[1]','NVARCHAR(50)') AS [Code]
, c.value('(SHORT_NAME/text())[1]','NVARCHAR(100)') AS [ShortName]
, c.value('(NAME/text())[1]','NVARCHAR(100)') AS [Name]
, c.value('(ADDRESS/text())[1]','NVARCHAR(100)') AS [LegalAddress]
, c.value('(STAN/text())[1]','NVARCHAR(50)') AS [Status]
FROM XmlFile CROSS APPLY xmlData.nodes('/DATA/RECORD') AS t(c);
-- test
SELECT * FROM #tbl;
-- Method #2
-- dynamic XML file name as a parameter
DECLARE #xml XML
, #sql NVARCHAR(MAX)
, #fileName VARCHAR(256) = 'c:\...\Ukraine.xml';
SET #sql = N'SELECT #xmlOut = XmlDoc FROM OPENROWSET (BULK ' + QUOTENAME(#fileName,NCHAR(39)) + ', SINGLE_BLOB) AS Tab(XmlDoc)';
EXEC master.sys.sp_executesql #sql, N'#xmlOut XML OUTPUT', #xmlOut = #xml OUTPUT;
INSERT INTO #tbl (Code, ShortName, [Name], LegalAddress, [Status])
SELECT c.value('(EDRPOU/text())[1]','NVARCHAR(50)') AS [Code]
, c.value('(SHORT_NAME/text())[1]','NVARCHAR(100)') AS [ShortName]
, c.value('(NAME/text())[1]','NVARCHAR(100)') AS [Name]
, c.value('(ADDRESS/text())[1]','NVARCHAR(100)') AS [LegalAddress]
, c.value('(STAN/text())[1]','NVARCHAR(50)') AS [Status]
FROM #xml.nodes('/DATA/RECORD') AS t(c);
-- test
SELECT * FROM #tbl;
I want to construct select query with dynamic where condition and insert into one temp table.
for eg.,
ALTER PROCEDURE asp_My_Proc
(
#empName nvarchar(50),
#limit_Operator nvarchar(2), -- Possible values '>' or '<'
#limit_Value int
)
INSERT INTO #table1
Select c1,c2,c3 from Employee where empName LIKE '%' + COALESCE(#empName, empName) + '%' and limit > 100
Proc Execution script:
EXECUTE asp_My_Proc
'John'
, '>'
,10
GO
Limit_value condition, I have to add limit condition based on 'limit_Operator' variable. How to construct this dynamically.
...
WHERE (#limit_Operator = '>' and t.limit > #limit_value)
OR (#limit_Operator = '<' and t.limit < #limit_value)
Dynamic sql only it is possible and that is best way to implement this to avoid sql injection
CREATE TABLE #EMP (
EMPNO INT PRIMARY KEY,
ENAME VARCHAR(10),
JOB VARCHAR(9),
MGR INT NULL,
HIREDATE DATETIME,
SAL NUMERIC(7,2),
COMM NUMERIC(7,2) NULL,
DEPT INT)
INSERT INTO #EMP VALUES
(1,'JOHNSON','ADMIN',6,'12-17-1990',18000,NULL,4)
INSERT INTO #EMP VALUES
(2,'HARDING','MANAGER',9,'02-02-1998',52000,300,3)
INSERT INTO #EMP VALUES
(3,'TAFT','SALES I',2,'01-02-1996',25000,500,3)
INSERT INTO #EMP VALUES
(4,'HOOVER','SALES I',2,'04-02-1990',27000,NULL,3)
INSERT INTO #EMP VALUES
(5,'LINCOLN','TECH',6,'06-23-1994',22500,1400,4)
INSERT INTO #EMP VALUES
(6,'GARFIELD','MANAGER',9,'05-01-1993',54000,NULL,4)
INSERT INTO #EMP VALUES
(7,'POLK','TECH',6,'09-22-1997',25000,NULL,4)
DECLARE
#EMPNAME NVARCHAR(50)='JOH',
#LIMIT_OPERATOR NVARCHAR(2)='>', -- POSSIBLE VALUES '>' OR '<'
#LIMIT_VALUE INT=100
DECLARE #A VARCHAR(MAX)
SET #A =CONCAT('
SELECT * FROM #EMP
WHERE ENAME LIKE ''%'' + COALESCE(''',#EMPNAME,''', ENAME) + ''%'' AND SAL ',#LIMIT_OPERATOR,' ',#LIMIT_VALUE,'','')
--EXEC (#A)
SELECT #A
As an example my database has 3 tables: People_Table, Address_Table and Gender_Table.
I want to insert
"First_Name", "Last_Name"
to the People_Table and
"Address_Line1", "Address_Line2", "City" & "Zip_Code"
to the Address_Table, and
"F" or "M"
to the Gender_Table.
For each entry I need to create a unique identifier with 8 character. The ID should look like this "N0000001", "N0000002", "N0000023"
How can I do this?
Thanks for your help!!!
You're making a mistake by making the database unique key the same as a visual business key.
You should instead use identity columns for your primary key (they autoincrement without any code required). Then you can create a calculated column on your table that for example turns the number 34563 into N0034563
What happens when your ID gets bigger than 9999999?
You need create a sequence table which have two columns number and tablegroupid. And you should create insert trigger. On trigger look sequence table for max number. And make them +1. Concatenate your prefix. And generate your custom identifier.
Here is one way to do this:
CREATE TABLES:
CREATE TABLE People_Table (
id_key VARCHAR(8)
,id INT
,firstname VARCHAR(50)
,lastname VARCHAR(50)
);
CREATE TABLE Address_Table (
id_key VARCHAR(8)
,Address_Line1 VARCHAR(50)
,Address_Line2 VARCHAR(50)
,City VARCHAR(50)
,Zip_Code VARCHAR(5)
);
CREATE TABLE Gender_Table (
id_key VARCHAR(8)
,Gender VARCHAR(1)
);
CREATE PROC:
Create a procedure to take your insert values as parameters and create separate insert statements for each table. Take max(id) from People_Table and increase by 1 before inserting it. To create your unique identifier key value, concatenate N and replication of 0's with your max(id) + 1.
CREATE PROCEDURE dbo.test_multipleinsert (
#FirstName VARCHAR(50)
,#LastName VARCHAR(50)
,#AddressLine1 VARCHAR(50)
,#AddressLine2 VARCHAR(50)
,#city VARCHAR(50)
,#zipcode VARCHAR(5)
,#gender VARCHAR(1)
)
AS
DECLARE #uniqueidentifier VARCHAR(8)
,#maxrowid INT;
SET NOCOUNT ON
BEGIN
SET #maxrowid = 0;
SELECT #maxrowid = max(id) + 1
FROM People_table;
SET #uniqueidentifier = 'N' + right(replicate(0, 7) + cast(#maxrowid AS VARCHAR(7)), 7);
INSERT INTO People_Table (
id_key
,id
,firstname
,lastname
)
VALUES (
#uniqueidentifier
,#maxrowid
,#firstName
,#lastName
);
INSERT INTO Address_Table (
id_key
,Address_Line1
,Address_Line2
,City
,Zip_Code
)
VALUES (
#uniqueidentifier
,#AddressLine1
,#AddressLine2
,#city
,#ZipCode
);
INSERT INTO Gender_Table (
id_key
,Gender
)
VALUES (
#uniqueidentifier
,#gender
);
END
EXECUTE PROC TO INSERT VALUES:
EXEC dbo.test_multipleinsert #FirstName = 'Michael'
,#LastName = 'Jordan'
,#AddressLine1 = '123 Main Street'
,#AddressLine2 = 'Apt#12'
,#City = 'CHICAGO'
,#ZipCode = '64601'
,#Gender = 'M';
EXEC dbo.test_multipleinsert #FirstName = 'Mark'
,#LastName = 'Johnson'
,#AddressLine1 = '456 Main Street'
,#AddressLine2 = 'Apt#89'
,#City = 'Atlanta'
,#ZipCode = '75859'
,#Gender = 'M';
SELECT *
FROM people_table;
SELECT *
FROM address_table;
SELECT *
FROM gender_table;
As a side note, your table is going to hit some major issues due to the your limitations on number of records you can have between 1 and 9999999 only.
I have the following stored procedure in SQL Server
IF OBJECT_ID ('kii.p_CreateSection') IS NOT NULL
DROP PROCEDURE kii.p_CreateSection
GO
CREATE PROCEDURE kii.p_CreateSection
#Name AS NVARCHAR(200),
#DocumentId AS INT,
#TypeId AS INT = NULL,
#ReportId AS INT = NULL,
#OrdinalPosition AS SMALLINT
AS
INSERT INTO kii.Section (Name, DocumentId, TypeId, ReportId, OrdinalPosition)
VALUES (#Name, #DocumentId, #TypeId, #ReportId, #OrdinalPosition)
SELECT SCOPE_IDENTITY();
GO
GRANT EXECUTE on kii.p_CreateSection TO p_role_kii
GO
The table Section is related to Document. Each document has several sections and they're ordered by the OrdinalPosistion value.
I'd like to test that if the given value for #OrdinalPosition is 0, then set it at the maximum value of all the sections of this Document +1.
Insert kii.Section( Name, DocumentId, TypeId, ReportId, OrdinalPosition )
Select #Name, #DocumentId, #TypeId, #ReportId
, Case
When #OrdinalPosition <> 0 Then #OrdinalPosition
Else (
Select Max( OrdinalPosition ) + 1
From kii.Section
Where DocumentId = #DocumentId
)
End