Creating and populating a table in T-SQL - sql

I'm new to T-SQL and trying to learn how to create a script in T-SQL to create and populate a table(StaffData).The StaffData is defined as below:
staffid – integer primary key, identity starting at 1, increments by 1
managerid – int, allows nulls, pointer to another record in managertable
name – string of 50 characters
salary – money
What can I do to generate table and fill it with set of data..?

Here's the correct SQL. I've tested it (just spotted that you want managerId nullable - I've added this):
it uses better conventions for your table and column names (you shouldn't be using 'data' in table names - we know it contains data)
it names your primary key constraints, which is better practice - you can do something similar for the FK constraint if you want, I've just done it inline
it uses 'USE' and 'GO' statements to ensure you're creating things on the right database (critical when you're working on big production systems).
it uses nvarchar columns - you need these to reliably store data from international character sets (e.g the manager has a Russian name)
I'm using nvarchar(max) as you can't be sure that a name will only be 50 characters. Use nvarchar(50) if you must, but database space isn't usually a big deal.
You need to create the Manager table first, as your Staff table depends on it:
USE [yourDatabaseName] -- you don't need the square brackets, but they don't hurt
-- Create ManagerTable
CREATE TABLE Manager
(
id int IDENTITY(1,1),
name nvarchar(max),
CONSTRAINT pk_manager PRIMARY KEY (id)
)
CREATE TABLE Staff
(
id int IDENTITY(1,1),
name nvarchar(max),
salary money,
managerId int FOREIGN KEY REFERENCES Manager(id) NULL,
CONSTRAINT pk_staff PRIMARY KEY (id)
)
--To populate Manager table:
INSERT INTO [Manager]
(
-- id column value is auto-generated
name
)
VALUES
(
'John Doe'
)
--To populate Staff table:
INSERT INTO [Staff]
(
-- id column value is auto-generated
name, salary, managerId
)
VALUES
(
'Jane Doe', 60000, 1
)
GO

To create the two database tables:
-- Create StaffData
CREATE TABLE StaffData
(
staffid int PRIMARY KEY IDENTITY,
managerid int
)
-- Create ManagerTable
CREATE TABLE ManagerTable
(
managerid int,
name varchar(50),
salary money
)
To populate StaffData table:
INSERT INTO [StaffData]
(
--staffid - this column value is auto-generated
[managerid]
)
VALUES
(
-- staffid - int
12345 -- managerid - int
)
To populate ManagerTable table:
INSERT INTO [ManagerTable]
(
[managerid],
[name],
[salary]
)
VALUES
(
12345, -- managerid - int
'Juan Dela Cruz', -- name - varchar
15000 -- salary - money
)
To select the data if i understand you in your word Pointer here is the query using INNER JOIN joining the two tables using their managerid
SELECT *
FROM [StaffData]
INNER JOIN [ManagerTable]
ON [StaffData].managerid = [ManagerTable].managerid

Related

Can't figure out Oracle update query involving two different tables

The SQL relation between two table is like below:
CREATE TABLE meve_hall (
hallNo NUMBER,
hallName varchar(20),
seatCapacity NUMBER,
PRIMARY KEY(hallNo)
)
CREATE TABLE meve_student (
stuId NUMBER,
name varchar(20),
dept varchar(20),
hallNo NUMBER,
PRIMARY KEY(stuId),
FOREIGN KEY(hallNo) REFERENCES meve_hall(hallNo)
)
Now the question is:
Change the hallName= 'Ziaur' of those students who is in dept='CSE'
You can write an UPDATE statement WHERE hallNo IN and a subquery to get the hallNo based on dept = 'CSE'.
UPDATE meve_hall SET hallName = 'Ziaur'
WHERE hallNo IN (SELECT hallNo FROM meve_student WHERE dept = 'CSE')
Demo here.

Dynamically created Tables JOIN in SQL Server

I have 3 types of tables
Major table as follows
CREATE TABLE #InitialTable
(
Id int PRIMARY KEY IDENTITY(1,1),
RP varchar(20)
)
INSERT INTO #InitialTable
VALUES ('R1', 'R2', 'R3')
GO
Table contains dynamically created tables information as follows
CREATE TABLE #DynamicTablesInfo
(
Id int PRIMARY KEY IDENTITY(1,1),
RPId int FOREIGN KEY REFERENCES #InitialTable(Id),
TableName varchar(100)
)
GO
INSERT INTO #DynamicTablesInfo
VALUES (1, 'Table_X1'), (2, 'Table_X2'), (3, 'Table_X3')
GO
Dynamically created tables these tables can be any number of tables and the tables info is available in above table.
CREATE TABLE #Table_X1
(
Id int PRIMARY KEY IDENTITY,
Version_Value varchar(100)
)
GO
INSERT INTO #Table_X1
VALUES ('Val_X1_1'), ('Val_X1_2'), ('Val_X1_3')
GO
CREATE TABLE #Table_X2
(
Id int PRIMARY KEY IDENTITY,
Version_Value varchar(100)
)
GO
INSERT INTO #Table_X2
VALUES ('Val_X2_1'), ('Val_X2_2'), ('Val_X2_3')
GO
CREATE TABLE #Table_X3
(
Id int PRIMARY KEY IDENTITY,
Version_Value varchar(100)
)
GO
INSERT INTO #Table_X3
VALUES ('Val_X3_1'), ('Val_X3_2'), ('Val_X3_3')
GO
Now I wanted to join InitialTable with dynamically created tables (Table_X1, Table_X2, Table_X3,....) with the help of DynamicTablesInfo table - how to do that?
Note: for easy update, delete, insert I created them as temporary tables but in my application all are real tables.
Instead of doing this:
CREATE TABLE #Table_X1
(
Id int PRIMARY KEY IDENTITY
,Version_Value varchar(100)
)
GO
CREATE TABLE #Table_X2
(
Id int PRIMARY KEY IDENTITY
,Version_Value varchar(100)
)
GO
CREATE TABLE #Table_X3
(
Id int PRIMARY KEY IDENTITY
,Version_Value varchar(100)
)
GO
Do this one time:
CREATE TABLE Table_X
(
Id int PRIMARY KEY IDENTITY
,Version_Value varchar(100)
,X_number INT
)
GO
Then instead of doing this:
INSERT INTO #Table_X1 VALUES ('Val_X1_1'),('Val_X1_2'),('Val_X1_3')
INSERT INTO #Table_X2 VALUES ('Val_X2_1'),('Val_X2_2'),('Val_X2_3')
INSERT INTO #Table_X3 VALUES ('Val_X3_1'),('Val_X3_2'),('Val_X3_3')
Do this:
INSERT INTO Table_X VALUES ('Val_X1_1',1),('Val_X1_2',1),('Val_X1_3',1)
INSERT INTO Table_X VALUES ('Val_X2_1',2),('Val_X2_2',2),('Val_X2_3',2)
INSERT INTO Table_X VALUES ('Val_X3_1',3),('Val_X3_2',3),('Val_X3_3',3)
Much easier to query without dynamics:
--no
SELECT * FROM Table_X1
--yes
SELECY * FROM Table_X WHERE X_Number = 1
You've indicated you're stuck with it how it is, so you'll need to create and run your queries dynamically too. This is c#/vb flavored pseudocode:
string sql = "SELECT * FROM sometable"
for int x = 1 to 3
sql = sql + " table_x{x} on sometable.id = table_x{x}.id"
Or perhaps build a Union:
string sql = "WITH allx AS (SELECT * FROM table_x1"
for int x = 2 to 10
sql = sql + " UNION ALL SELECT * FROM table_x{x}"
sql = sql + ") select * from sometable inner join allx on..."
But I echo larnu's sentiments in the comments.. if you truly cannot change the tables that are created, consider creating a VIEW in a similar way to the UNION code above, that will sit alongside X number of tables and will provide a way to query without dynamic:
CREATE VIEW AllX AS(
SELECT x.*, 1 as Which FROM TABLE_X1 x
UNION ALL SELECT x.*, 2 as Which FROM TABLE_X2 x
UNION ALL SELECT x.*, 3 as Which FROM TABLE_X3 x
...
Use the same technique that creates 10 tables to string together a CREATE VIEW statement that views over the 10 tables, then you can query the view without Dynamic sql generation

How to generate unique incremental employee code(pattern: E0001, E0002, E0003, ... ) in the INSERT stored procedure in SQL Server?

I want to generate unique employee code at a time of inserting a single record in INSERT stored procedure.
First-time procedure call will generate employee code as E0001, the second call will generate E0002, ...
The expected output should look like,
EmployeeCode EmployeeName
-------------------------------
E0001 A
E0002 B
E0003 C
E0004 D
E0005 E
' '
' '
' '
E9999 ZZZ
You can embed a sequence value into a custom-formatted string in a default, and enforce it with a check constraint. Like this:
--drop table if exists Employee
--drop sequence seq_Employee
--go
create sequence seq_Employee
start with 1
increment by 1
go
CREATE TABLE Employee
(
EmployeeCode char(5) PRIMARY KEY
default 'E' + format((next value for seq_Employee),'0000' )
check (EmployeeCode like 'E[0-9][0-9][0-9][0-9]'),
EmployeeName VARCHAR(50) NOT NULL
)
go
insert into Employee(EmployeeName)
values ('A'),('B'),('C'),('D'),('E')
select *
from Employee
Outputs
EmployeeCode EmployeeName
------------ --------------------------------------------------
E0001 A
E0002 B
E0003 C
E0004 D
E0005 E
Use an identity column to create a unique id. Then use this column for references from other tables. You can create a code if you like as a computed column:
create table employees (
employeeId int identity(1, 1) primary key,
employeeName varchar(255),
employeeCode as (concat('E', format(employeeId, '00000')))
);
Here is a db<>fiddle.
Use a database sequence number in your procedure to provide you the values. In order to get the value 'E' appended, concatenate 'E' with the sequence number in the query.
Use this link to understand the concept of database sequence number in sql server
CREATE SEQUENCE dbo.Seq
START WITH 1
INCREMENT BY 1;
GO
DECLARE #T TABLE (
E_CODE VARCHAR(50) PRIMARY KEY,
E_Name VARCHAR(MAX)
);
INSERT INTO #T VALUES (CONCAT('E',FORMAT(NEXT VALUE FOR dbo.SEQ,'0000')),'A')
INSERT INTO #T VALUES (CONCAT('E',FORMAT(NEXT VALUE FOR dbo.SEQ,'0000')),'B')
INSERT INTO #T VALUES (CONCAT('E',FORMAT(NEXT VALUE FOR dbo.SEQ,'0000')),'C')
SELECT * FROM #T

how to move record from one database to another database

I have two database,where two table are same with all schema.
I want to move specific records of employees and employeesrates with all columns of both tables.
below is the query.
CREATE TABLE #emp
(
empID INT IDENTITY(1, 1) primary key ,
Firstname varchar(20)
);
CREATE TABLE #empRates
(
ID INT IDENTITY(1, 1) primary key ,
empid int, -- foreign key from #emp
rate decimal(10,3),
startdate datetime,
enddate datetime,
);
insert into #emp (firstname) values('First')
insert into #emp (firstname) values('Second')
insert into #emp (firstname) values('Third')
insert into #empRates(empid,rate,startdate,enddate) values(1,10,'2020/01/10','2020/01/20')
insert into #empRates(empid,rate,startdate,enddate) values(1,15,'2020/01/20','2020/01/30')
insert into #empRates(empid,rate,startdate,enddate) values(2,10,'2020/01/10','2020/01/20')
insert into #empRates(empid,rate,startdate,enddate) values(3,15,'2020/01/20','2020/01/30')
select * from #emp
select * from #empRates
drop table #emp
drop table #empRates
Here both database on same server. Database1 and Database2.
below my query which tried.
insert into database2..empRates(empid,rate,startdate,enddate) select empid,rate,startdate,enddate
from database1..empRates
Here my problem is both database have different records,so identity are different,so after insert other employee rates get displayed for another like mashed up.
I am using sql server 2012.
can you please provide the way.
You should take a look at this post --> How to turn IDENTITY_INSERT on and off using SQL Server 2008?
This way you can specify value for id column during insert, so rows on destination databases will keep IDs from origin.
Hope it helps!

Update records based on inserted IDs and another non source column in SQL

Probably there is already answer for it, but i couldn't find it... So i have 2 tables and data in third one. Lets name them (Source, Target and UpdateTarget).
I need to insert records from Source to Target, then grab autoincremented IDs from Target and update UpdateTarget table with these IDs based on filters from Source table. I've tried to use OUTPUT, but it gives me an error:
The multi-part identifier "s.EmployeeID" could not be bound.
Here is my current SQL query:
CREATE TABLE dbo.target
(
id INT IDENTITY(1,1) PRIMARY KEY,
employee VARCHAR(32)
);
CREATE TABLE dbo.source
(
id INT IDENTITY(1,1) PRIMARY KEY,
employee VARCHAR(32),
EmployeeID int
);
CREATE TABLE dbo.updateTarget
(
id INT IDENTITY(1,1) PRIMARY KEY,
ExternalID int
);
DECLARE #MyTableVar TABLE
(
id INT,
EmployeeID int
);
INSERT dbo.target (employee)
OUTPUT
inserted.id, -- autoincremented ID
s.EmployeeID -- here i got an error
INTO #MyTableVar
SELECT s.employee
FROM dbo.source AS s
UPDATE dbo.updateTarget
SET ExternalID = data.ID
FROM #MyTableVar data
WHERE updateTarget.ID = data.EmployeeID
DROP TABLE source
DROP TABLE target
DROP TABLE updateTarget
I don't have EmployeeID column in target table.
Is there a way to achieve it without making two queries for each record? Or can you point me to existing answer if there are any?
Thanks!
1) INSERT INTO table variable generated id, and EmployeeId for usage in update
2) MERGE instead of INSERT (it allows to get column EmployeeId from SRC)
3) OUTPUT result, action inserted, getting id from TGT and EmployeeId
INSERT INTO #MyTableVar(id, EmployeeId)
SELECT id, EmployeeId
FROM (
MERGE dbo.target TGT
USING dbo.source SRC
ON TGT.employee = SRC.employee
WHEN NOT MATCHED THEN
INSERT (employee)
VALUES (src.employee)
OUTPUT inserted.id, SRC.EmployeeId)
AS out(id, EmployeeId);;
MERGE gives better OUTPUT options