Formulation of insert into keyword in SQL Server - sql

I want to insert some values to the table, there is an order such as 1,2,3....n
Insert Into table_name VALUES ( '1', 'A' )
Insert Into table_name VALUES ( '2', 'AA' )
Insert Into table_name VALUES ( '3', 'AAC' )
Insert Into table_name VALUES ( '.', '....' )
Insert Into table_name VALUES ( '.', '....' )
Insert Into table_name VALUES ( 'n', '....' )
How can I formulate this INSERT statement?

If you want to insert a series of rows - sure, you can use a loop - but how do you know what other values (other than the index) to get??
DECLARE #index INT
SET #index = 0
WHILE #index < 10
BEGIN
INSERT INTO dbo.table_name(Index)
VALUES( CAST(#index AS VARCHAR(50)) ) -- or whatever type you need....
SET #index = #index + 1
END

The usual way to do this is to select the values to insert from somewhere else:
INSERT INTO company1.new_customers (id, name, address)
SELECT
NULL -- this will trigger the DB to auto-generate the new id's
,name
,address
FROM company2.old_customers
If you have to use a loop in SQL you're doing it wrong.
SQL works with sets.

Related

SQL output of dynamic queries should be in csv

Referring to the code in one of the links found in the internet - that executes sql command stored in DB column
I was trying to get similar output in the form of csv - like query and data along with headers in one result.
Like if we have this data in sql server 2014
CREATE TABLE Table1 (empid INT,
name VARCHAR(1000),
sal INT,
DOB DATETIME,
OrgID INT);
CREATE TABLE Table2 (OrgID INT,
Orgname VARCHAR(1000));
CREATE TABLE Table3 (dummy INT);
INSERT INTO Table1
VALUES (100, 'tst', '10000', '1990-11-20', 1);
INSERT INTO Table1
VALUES (101, 'tst', '10000', '1990-11-20', 1);
INSERT INTO Table1
VALUES (102, 'tst', '10000', '1990-11-20', 2);
INSERT INTO Table2
VALUES (1, 'org1');
INSERT INTO Table2
VALUES (2, 'org2');
CREATE TABLE #List (Command VARCHAR(MAX),
OrderBy INT IDENTITY(1, 1));
INSERT INTO #List
VALUES ('SELECT * FROM Table1'),
('SELECT * FROM Table2'),
('SELECT * FROM Table3');
DECLARE #sqlcmd VARCHAR(MAX);
SELECT #sqlcmd = STUFF(
(SELECT ';' + CHAR(10) + Command + CHAR(10)FROM #List ORDER BY [OrderBy] FOR XML PATH('')), 1, 1, '');
EXEC (#sqlcmd);
Now when i execute the sql's in #List, the output should result with comma seperated.
As they are no records in table3, it should not output in final result.
Am expected the the result all in one column seperated by comma - screenshot attached.
OUTPUT
SELECT FROM Table1, empid,name,sal,DOB,OrgID
SELECT FROM Table1, 100,tst,10000,1990-11-20 00:00:00.000,1
SELECT FROM Table1, 101,tst,10000,1990-11-20 00:00:00.000,1
SELECT FROM Table1, 102,tst,10000,1990-11-20 00:00:00.000,2
select from Table2,OrgID, Orgname
select from Table2,1,org1
select * from Table2,2,org2

Sql Server While Loop with Changing Condition

I have a User Table in my database that contains two fields
user_id
manager_id
I am trying to construct a query to list all of the manager_ids that are associated with a user_id in a hierarchical structure.
So if i give a user_id, i will get that users manager, followed by that persons manager all the way to the very top.
So far i have tried but it doesnt give what i need:
WITH cte(user_id, manager_id) as (
SELECT user_id, manager_id
FROM user
WHERE manager_id=#userid
UNION ALL
SELECT u.user_id, u.manager_id,
FROM user u
INNER JOIN cte c on e.manager_id = c.employee_id
)
INSERT INTO #tbl (manager_id)
select user_id, manager_id from cte;
If anyone can point me in the right direction that would be great.
I thought about a While loop but this may not be very efficient and im not too sure how to implement that.
OP asked for a while loop, and while (ha, pun) this may not be the best way... Ask and you shall receive. (:
Here is sample data I created (in the future, please provide this):
CREATE TABLE #temp (userID int, managerID int)
INSERT INTO #temp VALUES (1, 3)
INSERT INTO #temp VALUES (2, 3)
INSERT INTO #temp VALUES (3, 7)
INSERT INTO #temp VALUES (4, 6)
INSERT INTO #temp VALUES (5, 7)
INSERT INTO #temp VALUES (6, 9)
INSERT INTO #temp VALUES (7, 10)
INSERT INTO #temp VALUES (8, 10)
INSERT INTO #temp VALUES (9, 10)
INSERT INTO #temp VALUES (10, 12)
INSERT INTO #temp VALUES (11, 12)
INSERT INTO #temp VALUES (12, NULL)
While Loop:
CREATE TABLE #results (userID INT, managerID INT)
DECLARE #currentUser INT = 1 -- Would be your parameter!
DECLARE #maxUser INT
DECLARE #userManager INT
SELECT #maxUser = MAX(userID) FROM #temp
WHILE #currentUser <= #maxUser
BEGIN
SELECT #userManager = managerID FROM #temp WHERE userID = #currentUser
INSERT INTO #results VALUES (#currentUser, #userManager)
SET #currentUser = #userManager
END
SELECT * FROM #results
DROP TABLE #temp
DROP TABLE #results
Get rid of this column list in your CTE declaration that has nothing to do with the columns you are actually selecting in the CTE:
WITH cte(employee_id, name, reports_to_emp_no, job_number) as (
Just make it this:
WITH cte as (
I recommend recursive solution:
WITH Parent AS
(
SELECT * FROM user WHERE user_id=#userId
UNION ALL
SELECT T.* FROM user T
JOIN Parent P ON P.manager_id=T.user_id
)
SELECT * FROM Parent
To see demo, run following:
SELECT * INTO #t FROM (VALUES (1,NULL),(2,1),(3,2),(4,1)) T(user_id,manager_id);
DECLARE #userId int = 3;
WITH Parent AS
(
SELECT * FROM #t WHERE user_id=#userId
UNION ALL
SELECT T.* FROM #t T
JOIN Parent P ON P.manager_id=T.user_id
)
SELECT * FROM Parent

Increment an ID within an INSERT INTO statement in AS400

Is there a way to insert a new record to a table that has an non-unique id and set this id to the next number in the same SQL statement?
Something like
INSERT INTO T1 (id, fname, lname)
VALUES ([last id + 1], 'Dan', 'Thomson');
this probably works
INSERT INTO T1 (id, fname, lname)
VALUES (ifnull((select max(id) from T1),0) + 1, 'Dan', 'Thomson')
DECLARE #COUNTER INT;
SET #COUNTER = 1;
WHILE(#COUNTER <= XXX)
BEGIN
INSERT INTO T1 (id, fname, lname)
VALUES (#COUNTER, #FNAME , #LNAME);
SET #COUNTER = #COUNTER + 1;
END
Built-in function MAX :
INSERT INTO T1 (id, fname, lname)
SELECT ifnull(MAX(id)+ 1,1), 'Dan', 'Thomson' FROM T1
Insert and set value with max()+1 problems
SELECT MAX(col) +1 is not safe -- it does not ensure that you aren't inserting more than one customer with the same customer_id value, regardless if selecting from the same table or any others.
For performance, add an index:
CREATE INDEX T1_INDEX1 ON T1 (id) DESC
References:
MAX()
CREATE INDEX
Index Advisor, Show Statements
Accelerated analytics - faster aggregations using the IBM DB2 for i encoded vector index (EVI) technology
Unit Test
-- Create Table
SET SCHEMA QTEMP;
CREAT TABLE testtbl (
id integer not null default,
fname char(10) not null default,
lname char(10) not null default)
;
-- Initialize Table with Data
insert into
testtbl ( id , fname, lname)
values
( 1, 'fname1', 'lname_1'),
( 2, 'fname2', 'lname_2'),
( 2, 'fname3', 'lname_3'),
( 3, 'fname4', 'lname_4')
;
-- Test Insert Statement
INSERT INTO
testtbl ( id, fname, lname )
SELECT ifnull(MAX( id ) + 1, 1), 'Dan', 'Thomson' FROM testtbl;
--Confirm Expectation
select * from testtbl;
ID FNAME LNAME
-------------------------------------
1 fname1 lname_1
2 fname2 lname_2
3 fname4 lname_4
4 Dan Thomson
if you want insert all content of table with unique id start with max +1
INSERT INTO T1 (id, fname, lname)
select
rownumber() over() + ifnull((select max(T1.id) from T1), 0),
T2.zone1, T2.zone2
from T2

generate custom id with conditions while inserting records to sql server

How can I generate custom ids upon inserting records base on a condition? For example, I have a donor database program which accepts donations from non-alumni and alumni. Custom id from an alumni should start on A00001 and for non-alumni is N00001. And to note, the record that will be inserted will come from another table which records came from an excel file.
Any help or clarifications would be appreciated.
Something like this perhaps?
DECLARE #Table TABLE ( ID VARCHAR(20) );
-- Non alumni
INSERT INTO #Table
( ID )
VALUES ( 'N00011' )
INSERT INTO #Table
( ID )
VALUES ( 'N00012' )
INSERT INTO #Table
( ID )
VALUES ( 'N00013' )
-- Alumni
INSERT INTO #Table
( ID )
VALUES ( 'A00011' )
INSERT INTO #Table
( ID )
VALUES ( 'A00012' )
INSERT INTO #Table
( ID )
VALUES ( 'A00013' )
-- Insert Alumni
INSERT INTO #Table
( ID
)
SELECT 'A' + RIGHT('00000'
+ CAST(MAX(RIGHT(ID, LEN(ID) - 1)) + 1 AS VARCHAR(10)),
5)
FROM #Table
WHERE LEFT(ID, 1) = 'A'
-- Insert Non Alumni
INSERT INTO #Table
( ID
)
SELECT 'N' + RIGHT('00000'
+ CAST(MAX(RIGHT(ID, LEN(ID) - 1)) + 1 AS VARCHAR(10)),
5)
FROM #Table
WHERE LEFT(ID, 1) = 'N'

Stored procedure to do a two-level pivot

I am trying to create a stored procedure in Sybase Adaptive Server Anywhere that will do a double pivot of table. I will first outline with some images what I am trying to accomplish.
The problem
Raw data
Here is the raw data in the table; in the sample code that I have posted lower down this is temporary table #t1 :
First level of pivoting
The first level of pivoting involves grouping on the column rownr and pivoting on the column col, putting the resulting table into temporary table #t2 :
I have the code up to this point which I have posted lower down.
Second level of pivoting
This is the section that I am struggling with. I am now needing to pivot table #t2 grouping on the column ObjectId and replicating the columns Operation and Code for the number of rows in the grouping to produce table #t3. So the result for the example I have given would look like this:
Because two columns are being replicated (Operation and Code) the number of columns in the resulting table should equal 2 multiplied by the number of rows in the grouping with the largest number of rows. Groupings that have less than the maximum number of grouped rows will be padded with null values, as seen in the example.
The code
Here is my code that creates the first two tables, #t1 and #t2 :
begin
create table #t1(rownr int, col nvarchar(15), val nvarchar(300));
insert into #t1 values(1, 'ObjectId', 'A');
insert into #t1 values(1, 'Operation', 'Op1');
insert into #t1 values(1, 'Code', '101');
insert into #t1 values(2, 'ObjectId', 'A');
insert into #t1 values(2, 'Operation', 'Op2');
insert into #t1 values(2, 'Code', '102');
insert into #t1 values(3, 'ObjectId', 'B');
insert into #t1 values(3, 'Operation', 'Op3');
insert into #t1 values(3, 'Code', '103');
insert into #t1 values(4, 'ObjectId', 'B');
insert into #t1 values(4, 'Operation', 'Op4');
insert into #t1 values(4, 'Code', '104');
insert into #t1 values(5, 'ObjectId', 'B');
insert into #t1 values(5, 'Operation', 'Op5');
insert into #t1 values(5, 'Code', '105');
-- Create t2
select
rownr,
Max(case when col = 'ObjectId' then val end) as ObjectId,
Max(case when col = 'Operation' then val end) as Operation,
Max(case when col = 'Code' then val end) as Code
into #t2
from #t1
group by rownr
order by rownr, ObjectId;
select * from #t2;
-- Create #t3 <--- This is where I need help
end
Take note
Please note that I am trying to solve this for Sybase Adaptive Server Anywhere which does not have a pivot statement like Sql Server does, so a solution using a pivot statement will not help me.
You need each set of A, B, etc in a single temporary table with their ObjectIds, with an ordering integer 1,2,3,4 against the ObjectIDs, regardless of the string value of the op.
Getting such an ordered integer is normally easy with an IDENTITY, but you don't want it for all, you want it per A,B,C etc subset.
Thus if you can run a Cursor on each ObjectId value (A,B,C,etc.,) and get the integer ordered operations for those into a temp table, then you can pivot easily with multiple outer joins.
So:
create table #l(Id NUMERIC(8) IDENTITY, op VARCHAR(30), obj VARCHAR(300))
go
set identity_insert #l on
Get a cursor on the objectIds and loop like:
select Id = IDENTITY(8)
, t2.val op
, t1.val obj
into
existing table
#l
from #t1 t1, #t1 t2
where t1.col = 'ObjectId'
and t1.val = 'A' -- this would be the cursors value
and t1.rownr = t2.rownr
and t2.col = 'Operation'
You will then find that #l can be pivotted nicely with multipler outers, because you'll have a table like:
select * from #l order by 3,1
Id op obj
----------- ------ -----
1 Op1 A
2 Op2 A
1 Op3 B
2 Op4 B
3 Op5 B
Just in case this helps someone else, here is the code that I eventually came up with to accomplish the required double pivot:
begin
DECLARE #nr_of_columns smallint;
DECLARE #qry long varchar;
DECLARE #i SMALLINT;
DECLARE #createTable nvarchar(1000);
create table #t1(rownr int, col nvarchar(15), val nvarchar(300));
insert into #t1 values(1, 'ObjectId', 'A');
insert into #t1 values(1, 'Operation', 'Op1');
insert into #t1 values(1, 'Code', '101');
insert into #t1 values(2, 'ObjectId', 'A');
insert into #t1 values(2, 'Operation', 'Op2');
insert into #t1 values(2, 'Code', '102');
insert into #t1 values(3, 'ObjectId', 'B');
insert into #t1 values(3, 'Operation', 'Op3');
insert into #t1 values(3, 'Code', '103');
insert into #t1 values(4, 'ObjectId', 'B');
insert into #t1 values(4, 'Operation', 'Op4');
insert into #t1 values(4, 'Code', '104');
insert into #t1 values(5, 'ObjectId', 'B');
insert into #t1 values(5, 'Operation', 'Op5');
insert into #t1 values(5, 'Code', '105');
-- create t2
select
rownr,
Max(case when col = 'ObjectId' then val end) as ObjectId,
Max(case when col = 'Operation' then val end) as Operation,
Max(case when col = 'Code' then val end) as Code
into #t2
from #t1
group by rownr
order by rownr, ObjectId;
-- create #t3
-- Maximum number of column groups in result table
select max(cols) into #nr_of_columns from (SELECT count() over (partition by ObjectId) as cols from #t2) A;
-- Create temporary table #t3 to hold results
SET #i = 1;
SET #createTable = 'create table #t3(ObjectId nvarchar(300)';
while #i <= #nr_of_columns loop
set #createTable = #createTable || ', Operation' || #i || ' nvarchar(300), Code' || #i || ' nvarchar(300)';
set #i = #i + 1;
end loop;
set #createTable = #createTable || ')';
execute immediate (#createTable);
-- Pivot into #t3
for whatever as cur cursor for
select 'insert into #t3 select ' || rw as qry from
(select '''' || A.ObjectId || ''' AS ObjectId, ' || LIST(attributes) || repeat(',null,null', #nr_of_columns-A.nr_in_group) AS rw from
(SELECT ObjectId, count() over (partition by ObjectId) nr_in_group, row_number() over (partition by ObjectId order by Operation) nr, ''''||Operation||''' AS Operation' || nr || ',' || '''' || Code || ''' AS Code' || nr as attributes FROM #t2 order by ObjectId,Operation) A
group by ObjectId,#nr_of_columns, nr_in_group) B
DO
execute IMMEDIATE (qry);
end for;
-- Output #t2
select * from #t3;
end