I have table product, product_sn
for every product have one or mutltiple sn ( serialNumber)
so lets imagine I ve product id = 11, productName = 'milk' I want copy all serialNumber from produt_sn into table product
declare table product (
id int identity(1,1) primary key,
productName varchar(100),
serialNumber BIGINT
)
declare table product_sn (
serialNumber BIGINT
)
product_sn (
867635017749586,
867635017734984,
867635017753893,
867635017724894,
867635017749727,
867635017725289,
867635017752739,
867635017724761,
867635017756193,
867635017756268
)
declare #sn bigint
select #sn from product_sn
insert into product values (id,productName,#sn) ??
declare #sn bigint
select #sn from product_sn
This will definitely throw an error here because you're attempting to select multiple rows into a single variable.
To correct that issue, try the following:
insert into product(serialnumber)
select serialnumber
from product_sn
I am only guessing here since you haven't provided the actual error, but it seems you are trying to insert value to field which is defined as identity, well don't.
just write :
insert into product values (productName,#sn)
Related
I'm new in query and SQL server, and I wanted to know about DDL.
I have an attribute in my Table which has more than 1 value, such as
Size = {'S', 'M', 'L'}.
How could i make the attribute in my Table with query, so i can insert multi values to one of my attribute?
You don't want to do this, because this is denormalizing your data. But, if you must.
declare #table table (id int identity(1,1), size varchar(16))
insert into #table
values
('S')
,('M')
select * from #table
update #table
set size = size + ',M'
where id = 1
select * from #table
Here is a one to many approach with a foreign key
create table #items (id int identity(1,1), descrip varchar(64))
insert into #items
values
('shirt'),
('pants')
create table #item_sizes (id int identity(1,1), size char(1), item_id int)
alter table #item_sizes
add constraint FK_item foreign key (item_id) references #items(id)
insert into #item_sizes
values
('S',1)
,('M',1)
,('L',1)
,('S',2)
select
ItemID = i.id
,i.descrip
,isiz.size
from #items i
inner join #item_sizes isiz
on isiz.item_id = i.id
drop table #items, #item_sizes
As per your requirement :
Product (...,ProductSize);
INSERT INTO Product (ProductSize) VALUES ('S')
How to query the row of ProductSize so i can insert more than one values in SQL? –
you can query like below
select * from Product where ProductSize like '%S%' or ProductSize like '%L%' or ProductSize like '%M%'
I have a temp table in SQL 2014. In this table variable I have an identity column declared.
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY
, IncidentResolvedOn date
, IncidentCreatedOn date
, IncidentClosedOn date
, TaskAssigned date
, TaskCompleted date
, TaskID float
, IncidentTeamID int
, TotalDaysOutstanding int
, TierInfo varchar(15)
, Task_NoTask varchar(15)
, Tier_2_Days_Outstanding int
, Tier_1_Days_Outstanding int
, DaysToResolve int
, BadDays int
, StartDate date
, EndDate date
)
When I run the rest of the query the ID column sometimes doesn't start with 1, instead it starts with some random number. The code below is what I use to insert into this table variable.
INSERT INTO #TempTable(IncidentResolvedOn, IncidentCreatedOn, IncidentClosedOn,TaskAssigned, TaskCompleted, TaskID, IncidentTeamID )
SELECT [Incident Resolved On]
, [Incident Created On]
, [Incident Closed On]
, [Task Assigned On]
, [Task Completed On]
, [Task ID]
, IncidentTeamID
FROM HEATData
This happens in both a table variable and temp table. I've never seen this happen before. Usually when I use the IDENTITY(1,1) phrase it always starts with 1 no matter how many times I create that table. Any suggestions out there?
I imagine your connection is staying open and thus, your identity isn't resetting for your local variable. Here's an example.
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY,
ID2 int)
insert into #TempTable
values
(1),(2)
select * from #TempTable
delete from #TempTable
insert into #TempTable
values
(1),(2)
select * from #TempTable
Now, if you'd wrap this in it's own batch using GO you could see this wouldn't happen. In fact, you have to re-declare your table variable.
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY,
ID2 int)
insert into #TempTable
values
(1),(2)
select * from #TempTable
go
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY,
ID2 int)
insert into #TempTable
values
(1),(2)
select * from #TempTable
This would be the same for a #TempTable as well if you didn't explicitly drop the #TempTable or the connection remained open. Of course, for actual tables the increment will continue similarly to the first examaple.
I have a XML block which I want to insert into database. database contains 3 tables namely itemMapping, links and category. Links table will have only link from XML, category table will have category from XML.
<item>
<link>http://google.com</link>
<category>search engine</category>
<category>android</category>
<category>gmail</category>
</item>
Here come my confusion, 'itemMaping' table contains following columns :
ID, LinkID, CategoryID
In itemMapping table I have to insert linkID and categoryID of newly inserted rows. So according to sample XML itemMapping table will have 3 records for each category, but to insert record in this table i will need linkID and categoryID from above. How I can achieve this? I want to do this in single SP if possible.
Hi Consider the following tables:
Country Table
CountryID CountryName LastEditUser
Province table
ProvinceID ProvinceName CountryID LastEditUser
Consider CountryID and ProvinceID were identity columns.
IN SQL YOU can insert records to these two tables using a single stored procedure take a look at the quick example
CREATE PROCEDURE InsertProvince
(
#ProvinceName VARCHAR(128),
#CountryName VARCHAR(128),
#LastEditUser VARCHAR(128)
)
AS
DECLARE #CountryID INT
INSERT INTO Country
(CountryName, LastEditUser)
VALUES
(#CountryName, #LastEditUser)
#CountryID = SCOPE_IDENTITY();
INSERT INTO Province
(ProvinceName, CountryID, LastEditUser)
VALUES
(#ProvinceName, #CountryID, #LastEditUser)
END
SQL Server has a function called scope_identity, it returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.
Insert into Links and capture the LinkID with scope_identity() to a variable. Insert into Category and capture the generated ID's in a table variable. Use that table variable as source for the insert to ItemMapping.
Assuming your tables look like this.
create table Category
(
CategoryID int identity primary key,
Name varchar(50)
)
create table Links
(
LinkID int primary key identity,
Link varchar(50)
)
create table ItemMapping
(
LinkID int references Links(LinkID),
CategoryID int references Category(CategoryID),
primary key(LinkID, CategoryID)
)
You can do like this using an XML variable #XML.
declare #IDs table(ID int)
declare #LinkID int
insert into Links(Link)
select T.X.value('.', 'nvarchar(50)')
from #XML.nodes('item/link') as T(X)
set #LinkID = scope_identity()
insert into Category(Name)
output inserted.CategoryID into #IDs
select T.X.value('.', 'nvarchar(50)')
from #XML.nodes('item/category') as T(X)
insert into ItemMapping(LinkID, CategoryID)
select #LinkID, I.ID
from #IDs as I
SE-Data
I'm writing a SQL script to generate test data for our database. I'm generating the data in table variables (so I can track it later) and then inserting it into the real tables. The problem is, I need to track which rows I've added to the parent table, so that I can generate its child data later on in the script. For example:
CREATE TABLE Customer (
CustomerId INT IDENTITY,
Name VARCHAR(50)
)
CREATE TABLE Order (
OrderId INT IDENTITY,
CustomerId INT,
Product VARCHAR(50)
)
So, in my script, I create equivalent table variables:
DECLARE #Customer TABLE (
CustomerId INT IDENTITY,
Name VARCHAR(50)
) -- populate customers
DECLARE #Order TABLE (
OrderId INT IDENTITY,
CustomerId INT,
Product VARCHAR(50)
) -- populate orders
And I generate and insert sample data into each table variable.
Now, when I go to insert customers from my table variable into the real table, the CustomerId column in the table variable will become meaningless, as the real table has its own identity seed for its CustomerId column.
Is there a way I can track the new identity of each row inserted into the real table, in my table variable, so I can use a proper CustomerId for the order records? Or, is there a better way I should be going about this?
(Note: I originally started with an application to generate the test data, but it ran too slow during insert as > 1,000,000 records need to be generated.)
WHy do you need identity values on the table variables? If you use just int, you can isnert the ids after the insert is done. Grab them using the output clause. YOu might need an input values and an output values table varaiable to get this just right like this:
DECLARE #CustomerInputs TABLE (Name VARCHAR(50) )
DECLARE #CustomerOutputs TABLE (CustomerId INT ,Name VARCHAR(50) )
INSERT INTO CUSTOMERS (name)
OUTPUT inserted.Customerid, inserted.Name INTO #CustomerOutputs
SELECT Name FROM #CustomerInputs
SELECT * from #CustomerOutputs
You can insert the data to the table with a cursor and use the built-in function SCOPE_IDENTITY() to get the last id which was inserted in the current scope (by your script).
See this MSDN article for more information on SCOPE_IDENTITY.
Here is one way of doing it. If you can use it depends on your situation. You should not do it in production environment when users use your db.
-- Get the next identity values for Customer and Order
declare #NextCustomerID int
declare #NextOrderID int
set #NextCustomerID = IDENT_CURRENT('Customer')+1
set #NextOrderID = IDENT_CURRENT('Order')+1
-- Create tmp tables
create table #Customer (CustomerID int identity, Name varchar(50))
create table #Order (OrderID int identity, CustomerID int, Product varchar(50))
-- Reseed the identity columns in temp tables
dbcc checkident(#Customer, reseed, #NextCustomerID)
dbcc checkident(#Order, reseed, #NextOrderID)
-- Populate #Customer
-- Populate #Order
-- Allow insert to identity column on Customer
set identity_insert Customer on
-- Add rows to Customer
insert into Customer(CustomerId, Name)
select CustomerID, Name
from #Customer
-- Restore identity functionality on Customer
set identity_insert Customer off
-- Add rows to Order
set identity_insert [Order] on
insert into [Order](OrderID, CustomerID, Product)
select OrderID, CustomerID, Product
from #Order
set identity_insert [Order] off
-- Drop temp tables
drop table #Customer
drop table #Order
-- Check result
select * from [Order]
select * from Customer
The way I'd do it its first obtain the MAX(CustomerId) from your Customer Table. Then I'd get rid of the IDENTITY column on your variable table and do my own CustomerId using ROW_NUMBER() and the MaxCustomerId. It should be something like this:
DECLARE #MaxCustomerId INT
SELECT #MaxCustomerId = ISNULL(MAX(CustomerId),0)
FROM Customer
DECLARE #Customer TABLE (
CustomerId INT,
Name VARCHAR(50)
)
INSERT INTO #Customer(CustomerId, Name)
SELECT #MaxCustomerId + ROW_NUMBER() OVER(ORDER BY SomeColumn), Name
FROM YourDataTable
Or insert the values on a temp table, so you can use the same ids to fill your Order table.
Let us say I have a table (everything is very much simplified):
create table OriginalData (
ItemName NVARCHAR(255) not null
)
And I would like to insert its data (set based!) into two tables which model inheritance
create table Statements (
Id int IDENTITY NOT NULL,
ProposalDateTime DATETIME null
)
create table Items (
StatementFk INT not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk)
)
Statements is the parent table and Items is the child table. I have no problem doing this with one row which involves the use of IDENT_CURRENT but I have no idea how to do this set based (i.e. enter several rows into both tables).
Thanks.
Best wishes,
Christian
Another possible method that would prevent the use of cursors, which is generally not a best practice for SQL, is listed below... It uses the OUTPUT clause to capture the insert results from the one table to be used in the insert to the second table.
Note this example makes one assumption in the fact that I moved your IDENTITY column to the Items table. I believe that would be acceptable, atleast based on your original table layout, since the primary key of that table is the StatementFK column.
Note this example code was tested via SQL 2005...
IF OBJECT_ID('tempdb..#OriginalData') IS NOT NULL
DROP TABLE #OriginalData
IF OBJECT_ID('tempdb..#Statements') IS NOT NULL
DROP TABLE #Statements
IF OBJECT_ID('tempdb..#Items') IS NOT NULL
DROP TABLE #Items
create table #OriginalData
( ItemName NVARCHAR(255) not null )
create table #Statements
( Id int NOT NULL,
ProposalDateTime DATETIME null )
create table #Items
( StatementFk INT IDENTITY not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk) )
INSERT INTO #OriginalData
( ItemName )
SELECT 'Shirt'
UNION ALL SELECT 'Pants'
UNION ALL SELECT 'Socks'
UNION ALL SELECT 'Shoes'
UNION ALL SELECT 'Hat'
DECLARE #myTableVar table
( StatementFk int,
ItemName nvarchar(255) )
INSERT INTO #Items
( ItemName )
OUTPUT INSERTED.StatementFk, INSERTED.ItemName
INTO #myTableVar
SELECT ItemName
FROM #OriginalData
INSERT INTO #Statements
( ID, ProposalDateTime )
SELECT
StatementFK, getdate()
FROM #myTableVar
You will need to write an ETL process to do this. You may want to look into SSIS.
This also can be done with t-sql and possibly temp tables. You may need to store unique key from OriginalTable in Statements table and then when you are inserting Items - join OriginalTable with Statements on that unique key to get the ID.
I don't think you could do it in one chunk but you could certainly do it with a cursor loop
DECLARE #bla char(10)
DECLARE #ID int
DECLARE c1 CURSOR
FOR
SELECT bla
FROM OriginalData
OPEN c1
FETCH NEXT FROM c1
INTO #bla
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO Statements(ProposalDateTime) VALUES('SomeDate')
SET #ID = SCOPE_IDENTITY()
INSERT INTO Items(StateMentFK,ItemNAme) VALUES(#ID,#bla)
FETCH NEXT FROM c1
INTO #bla
END
CLOSE c1
DEALLOCATE c1