I have a question about SQL Server: how to change database name dynamically and use one select and insert statment to load data using a stored procedure.
How to change the database name with insert and select statement while table data loading into another table?
Here each database name related table load into with in the database name related target table.
i.e database: test and source table: emp target table is :emptarget here emp table records load into emptarget similar to another databases
Database names information maintain one table.
USE [test]
GO
CREATE TABLE [dbo].[databaseinformation]
(
[id] [int] NULL,
[databasename] [varchar](50) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[databaseinformation] ([id], [databasename])
VALUES (1, N'test'), (2, N'test1')
GO
Table1 : source : emp and datbasename: test
USE [test]
CREATE TABLE [dbo].[emp]
(
[id] [int] NULL,
[name] [varchar](50) NULL,
[sal] [int] NULL
)
INSERT [dbo].[emp] ([id], [name], [sal])
VALUES (19, N'hd', 40), (1, N'g', 10),
(9, N'dk', 90), (80, N'dhe', 80)
GO
Target table : emptarget and databasename: test
USE [test]
CREATE TABLE [dbo].[emptarget]
(
[id] [int] NULL,
[name] [varchar](50) NULL,
[sal] [int] NULL
)
----table 2: emp and databasename: test1
USE [test]
CREATE TABLE [dbo].[emp]
(
[id] [int] NULL,
[name] [varchar](50) NULL,
[sal] [int] NULL
)
INSERT [dbo].[emp] ([id], [name], [sal])
VALUES (50, N'kl', 80), 39, N'abc', 10)
go
Target table : emptarget and databasename: test1
USE [test1]
CREATE TABLE [dbo].[emptarget]
(
[id] [int] NULL,
[name] [varchar](50) NULL,
[sal] [int] NULL
)
Finally need to load data like below
Database: test and table : emptarget
id |name |sal
19 |hd |40
1 |g |10
9 |dk |90
80 |dhe |80
Database: test1 and table : emptarget
id |name |sal
50 |kl |80
39 |abc |10
I tried like below
USE [test]
GO
insert into emptarget
select * from emp
USE [test1]
GO
insert into emptarget
select * from emp
Here I do not want run two queries separately. I need to run querying using single select and insert statement to load data correspong tables with databases.
Please tell me how to write query to achive this task in SQL Server
Actually I have no idea about why you don't do this.
insert into test.emptarget select * from test.emp;
insert into test1.emptarget select * from test1.emp;
So I think you just want one query to do this.
create procedure emptoemptarget (#DBName nvarchar(10))
as
begin
declare #sql nvarchar(1000)
set #sql = 'insert into ' + #DBName + '.emptarget select * from ' + #DBName + '.emp'
exec (#sql)
end
select dbo.emptoemptarget(name) from sys.databases where name in ('test','test1')
Related
i need help to create a trigger, i have a database with this table: test01(id, name, id_parent)
CREATE TABLE [dbo].[test01](
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](64) NOT NULL,
CONSTRAINT [PK_test01] PRIMARY KEY CLUSTERED
(
[id] ASC
)
when an update is executed i need to copy the update row in the same table.
Example data before update
id, name, id_parent
1 , 'bob', null
2 , 'jak', null
if i send:
update test01 set name='newbob' where id=1
i need this result
id, name, id_parent
1 , 'newbob', null <---- updated row
2 , 'jak', null
3 , 'bob', 1 <---- copy of previous row with id_parent referenced to the updated row
i need help to create a trigger for this.
my non working version:
CREATE TRIGGER testtrg
ON test01
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
insert into test01
select * from inserted
END
GO
it works. you needed to map the id into the id_parent column
drop table test01
CREATE TABLE [dbo].[test01](
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](64) NOT NULL,
[id_parent][int] NULL,
CONSTRAINT [PK_test01] PRIMARY KEY CLUSTERED
(
[id] ASC
));
insert into test01 (name,id_parent)
values('bob', null),('jak', null)
select * from test01
CREATE TRIGGER testtrg
ON test01
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
insert into test01(name,id_parent)
select name,id from inserted
END
update test01 set name='bob2' where id=1
select * from test01
output:
id name id_parent
1 bob NULL
2 jak NULL
3 bob2 1
Find an example below of how we implement security filter predicate in SQL Server 2016. We have root tables on which we apply security rules and we want to rules to apply to detail/child tables. For example, if a sales rep create an order made of many shipments which contains many items, we don't want another sales rep to query those items.
USE [TestSecurity2016b]
GO
/****** Object: Table [dbo].[OrderDetails] Script Date: 2017-01-02 09:14:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Orders]
(
[ID] [int] NOT NULL,
[SalesRep] [sysname] NOT NULL,
) ON [PRIMARY]
CREATE TABLE [dbo].[OrderShipments]
(
[ID] [int] NOT NULL,
[FK_OrderID] [int] NOT NULL,
[TrackingNumber] [varchar](25) NULL,
[ShippedOn] [Date] NULL,
) ON [PRIMARY]
CREATE TABLE [dbo].[OrderShipmentItems]
(
[ID] [int] NOT NULL,
[FK_OrderShipmentID] [int] NOT NULL,
[Product] [varchar](25) NOT NULL,
[Quantity] [int] NOT NULL,
) ON [PRIMARY]
GO
insert dbo.Orders values
(1, 'SalesRep1'),
(2, 'SalesRep2');
insert dbo.[OrderShipments] values
(1, 1, '1234', '2016-12-25'),
(2, 1, '4321', '2016-12-26'),
(3, 2, '5678', '2017-01-01');
insert dbo.[OrderShipmentItems] values
(1, 1, 'Benq w1070', 1),
(2, 1, '#8 Stainless bolts', 4),
(3, 2, 'HP x360 Laptop', 1),
(4, 3, 'Nintendo NES', 1),
(5, 3, 'Intellivision', 1),
(6, 3, 'Coleco', 1);
GO
create user Manager without login;
create user SalesRep1 without login;
create user SalesRep2 without login;
GO
grant select on dbo.Orders to Manager;
grant select on dbo.[OrderShipments] to Manager;
grant select on dbo.[OrderShipmentItems] to Manager;
grant select on dbo.Orders to SalesRep1;
grant select on dbo.[OrderShipments] to SalesRep1;
grant select on dbo.[OrderShipmentItems] to SalesRep1;
grant select on dbo.Orders to SalesRep2;
grant select on dbo.[OrderShipments] to SalesRep2;
grant select on dbo.[OrderShipmentItems] to SalesRep2;
GO
create function dbo.fn_orderfilter_predicate(#SalesRep as sysname)
returns table
with schemabinding
as
return select 1 as result
where #SalesRep = user_name() or user_name() = 'Manager';
GO
create function dbo.fn_ordershipmentsfilter_predicate(#FK_OrderID as int)
returns table
with schemabinding
as
return select 1 as result
where #FK_OrderID in (select ID as OrdersID from dbo.Orders where SalesRep = user_name() or user_name() = 'Manager')
GO
create function dbo.fn_ordershipmentitemsfilter_predicate(#FK_OrderShipmentID as int)
returns table
with schemabinding
as
return select 1 as result
where #FK_OrderShipmentID in
(
SELECT OrderShipments.ID AS OrderShipmentID
FROM dbo.Orders INNER JOIN
dbo.OrderShipments ON Orders.ID = OrderShipments.FK_OrderID
WHERE (Orders.SalesRep = USER_NAME() OR USER_NAME() = 'Manager')
AND (OrderShipments.ID = #FK_OrderShipmentID)
)
GO
create security policy OrdersFilter
add filter predicate dbo.fn_orderfilter_predicate(SalesRep)
on dbo.Orders
with (state = on);
GO
create security policy OrderShipmentsFilter
add filter predicate dbo.fn_ordershipmentsfilter_predicate(FK_OrderID)
on dbo.OrderShipments
with (state = on);
GO
create security policy OrderShipmentItemsFilter
add filter predicate dbo.fn_ordershipmentitemsfilter_predicate(FK_OrderShipmentID)
on dbo.OrderShipmentItems
with (state = on);
GO
execute as user = 'SalesRep1';
select * from dbo.Orders;
select * from dbo.OrderShipments;
select * from dbo.OrderShipmentItems;
revert;
GO
execute as user = 'SalesRep2';
select * from dbo.Orders;
select * from dbo.OrderShipments;
select * from dbo.OrderShipmentItems;
revert;
GO
execute as user = 'Manager';
select * from dbo.Orders;
select * from dbo.OrderShipments;
select * from dbo.OrderShipmentItems;
revert;
GO
This presents a number of problems:
- As child level increases, complexity of predicate increases
- Changing the security rule on the root table requires changing the rules for all child tables.
Is there a way to solve those problems?
Thank you
I have the following three tables:
Please note that the below DDL came models generated by Django then grabbed out of Postgresql after they were created. So modifying the tables is not an option.
CREATE TABLE "parentTeacherCon_grade"
(
id INTEGER PRIMARY KEY NOT NULL,
"currentGrade" VARCHAR(2) NOT NULL
);
CREATE TABLE "parentTeacherCon_parent"
(
id INTEGER PRIMARY KEY NOT NULL,
name VARCHAR(50) NOT NULL,
grade_id INTEGER NOT NULL
);
CREATE TABLE "parentTeacherCon_teacher"
(
id INTEGER PRIMARY KEY NOT NULL,
name VARCHAR(50) NOT NULL
);
CREATE TABLE "parentTeacherCon_teacher_grade"
(
id INTEGER PRIMARY KEY NOT NULL,
teacher_id INTEGER NOT NULL,
grade_id INTEGER NOT NULL
);
ALTER TABLE "parentTeacherCon_parent" ADD FOREIGN KEY (grade_id) REFERENCES "parentTeacherCon_grade" (id);
CREATE INDEX "parentTeacherCon_parent_5c853be8" ON "parentTeacherCon_parent" (grade_id);
CREATE INDEX "parentTeacherCon_teacher_5c853be8" ON "parentTeacherCon_teacher" (grade_id);
ALTER TABLE "parentTeacherCon_teacher_grade" ADD FOREIGN KEY (teacher_id) REFERENCES "parentTeacherCon_teacher" (id);
ALTER TABLE "parentTeacherCon_teacher_grade" ADD FOREIGN KEY (grade_id) REFERENCES "parentTeacherCon_grade" (id);
CREATE UNIQUE INDEX "parentTeacherCon_teacher_grade_teacher_id_20e07c38_uniq" ON "parentTeacherCon_teacher_grade" (teacher_id, grade_id);
CREATE INDEX "parentTeacherCon_teacher_grade_d9614d40" ON "parentTeacherCon_teacher_grade" (teacher_id);
CREATE INDEX "parentTeacherCon_teacher_grade_5c853be8" ON "parentTeacherCon_teacher_grade" (grade_id);
My Question is: How do I write an insert statement (or statements) where I do not have keep track of the IDs? More specifically I have a teacher table, where teachers can teach relate to more than one grade and I am attempting to write my insert statements to start populating my DB. Such that I am only declaring a teacher's name, and grades they relate to.
For example, if I have a teacher that belong to only one grade then the insert statement looks like this.
INSERT INTO "parentTeacherCon_teacher" (name, grade_id) VALUES ('foo bar', 1 );
Where grades K-12 are enumerated 0,12
But Need to do something like (I realize this does not work)
INSERT INTO "parentTeacherCon_teacher" (name, grade_id) VALUES ('foo bar', (0,1,3) );
To indicate that this teacher relates to K, 1, and 3 grades
leaving me with this table for the parentTeacherCon_teacher_grade
+----+------------+----------+
| id | teacher_id | grade_id |
+----+------------+----------+
| 1 | 3 | 0 |
| 2 | 3 | 1 |
| 3 | 3 | 3 |
+----+------------+----------+
This is how I can currently (successfully) insert into the Teacher Table.
INSERT INTO public."parentTeacherCon_teacher" (id, name) VALUES (3, 'Foo Bar');
Then into the grade table
INSERT INTO public.parentTeacherCon_teacher_grade (id, teacher_id, grade_id) VALUES (1, 3, 0);
INSERT INTO public.parentTeacherCon_teacher_grade (id, teacher_id, grade_id) VALUES (2, 3, 1);
INSERT INTO public.parentTeacherCon_teacher_grade (id, teacher_id, grade_id) VALUES (3, 3, 3);
A bit more information.
Here is a diagram of the database
Other things I have tried.
WITH i1 AS (INSERT INTO "parentTeacherCon_teacher" (name) VALUES ('foo bar')
RETURNING id) INSERT INTO "parentTeacherCon_teacher_grade"
SELECT
i1.id
, v.val
FROM i1, (VALUES (1), (2), (3)) v(val);
Then I get this error.
[2016-08-10 16:07:46] [23502] ERROR: null value in column "grade_id" violates not-null constraint
Detail: Failing row contains (6, 1, null).
If you want to insert all three rows in one statement, you can use:
INSERT INTO "parentTeacherCon_teacher" (name, grade_id)
SELECT 'foo bar', g.grade_id
FROM (SELECT 0 as grade_id UNION ALL SELECT 1 UNION ALL SELECT 3) g;
Or, if you prefer:
INSERT INTO "parentTeacherCon_teacher" (name, grade_id)
SELECT 'foo bar', g.grade_id
FROM (VALUES (0), (2), (3)) g(grade_id);
EDIT:
In Postgres, you can have data modification statements as a CTE:
WITH i as (
INSERT INTO public."parentTeacherCon_teacher" (id, name)
VALUES (3, 'Foo Bar')
RETURNING *
)
INSERT INTO "parentTeacherCon_teacher" (name, teacher_id, grade_id)
SELECT 'foo bar', i.id, g.grade_id
FROM (VALUES (0), (2), (3)) g(grade_id) CROSS JOIN
i
This question already has answers here:
How to change identity column values programmatically?
(13 answers)
Closed 9 years ago.
ID EmployeeName Address PhoneNo EmailID DOB DOJ Designation Department CraetedDate
2 Sabarish Saidapet 9600387983 sabari#gmail.com -1973 -2012 Ase Software 2013-05-15 17:07:43.223
10 Karthik Chrompet 9865028330 karthik#gmail.com -1968 -2008 SoftwareEngineeer Software 2013-05-15 15:40:41.613
15 Sabarish Saidapet 9600387983 sabari#gmail.com -1973 -2012 Ase Software 2013-05-15 17:07:12.003
In the above table the id column is an identity column and I want my id values as 1,2,3, instead of 2,10,15 how to do this?
Try this one -
Query:
IF OBJECT_ID (N'dbo.test') IS NOT NULL
DROP TABLE dbo.test
CREATE TABLE dbo.test
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY
, EmployeeName VARCHAR(50) NOT NULL
)
SET IDENTITY_INSERT dbo.test ON
INSERT INTO dbo.test
(
ID
, EmployeeName
)
VALUES
(2, 'Sabarish Saidapet'),
(10, 'Karthik Chrompet'),
(15, 'Sabarish Saidapet')
SET IDENTITY_INSERT dbo.test OFF
SET IDENTITY_INSERT dbo.test ON
DECLARE #temp TABLE
(
ID INT NOT NULL
, EmployeeName VARCHAR(50) NOT NULL
)
INSERT INTO #temp (EmployeeName, ID)
SELECT
t.EmployeeName
, ROW_NUMBER() OVER (ORDER BY (SELECT 1))
FROM dbo.test t
TRUNCATE TABLE dbo.test
--DELETE FROM dbo.test
INSERT INTO dbo.test (ID, EmployeeName)
SELECT ID, EmployeeName FROM #temp
SET IDENTITY_INSERT dbo.test OFF
INSERT INTO dbo.test (EmployeeName)
VALUES ('test 4')
SELECT *
FROM dbo.test t
Output:
ID EmployeeName
----------- --------------------------------------------------
1 Sabarish Saidapet
2 Karthik Chrompet
3 Sabarish Saidapet
4 test 4
I want to "dynamically" create the result columns in a PostgreSQL query. I have these tables:
CREATE SEQUENCE users_id;
CREATE TABLE users (
id INT PRIMARY KEY NOT NULL DEFAULT NEXTVAL('users_id'),
name VARCHAR(128) NOT NULL
);
CREATE SEQUENCE quota_rules_id;
CREATE TABLE quota_rules (
id INT PRIMARY KEY NOT NULL DEFAULT NEXTVAL('quota_rules_id'),
user_id INT REFERENCES users(id),
rule VARCHAR(255) NOT NULL
);
CREATE INDEX user_id_index ON quota_rules(user_id);
INSERT INTO users (name) VALUES ('myname'); -- id=1
INSERT INTO quota_rules (user_id, rule) VALUES (1, 'a');
INSERT INTO quota_rules (user_id, rule) VALUES (1, 'b');
INSERT INTO quota_rules (user_id, rule) VALUES (1, 'c');
And want a query that returns this (1 row):
SELECT ............ user_id = 1;
name | quota_rule | quota_rule2 | quota_rule3
myname | a | b | c
Check out the crosstab function of the tablefunc module