Generating insert statement dynamically based on conditions - sql

I have two separate deployment of Student Table. In one case student table contains department Id and in other case it doesn't contain department Id.
I have a common post deployment script for both cases to insert value in student table.
CREATE TABLE dbo.Student
(
DeptId UNIQUEIDENTIFIER,
StudentName VARCHAR(20)
)
GO
DECLARE #DeptId UNIQUEIDENTIFIER
IF COL_LENGTH('dbo.Department', 'DeptId') IS NOT NULL BEGIN
SELECT #DeptId = DeptId
FROM dbo.Department
WHERE DeptName = 'Computer'
END
INSERT INTO dbo.Student(DeptId, StudentName)
SELECT #DeptId, 'TBAG'
But When I don't have department Id column this script doesn't work
Msg 207, Level 16, State 1, Line 23
Invalid column name 'DeptId'.

You can try something like this,
CREATE TABLE dbo.Student
(
DeptId UNIQUEIDENTIFIER,
StudentName VARCHAR(20)
)
GO
IF Col_length('dbo.Department', 'DeptId') IS NOT NULL
BEGIN
INSERT INTO dbo.Student
(DeptId,
StudentName)
SELECT DeptId,
'TBAG'
FROM dbo.Department
WHERE DeptName = 'Computer'
END
ELSE
BEGIN
INSERT INTO dbo.Student
(StudentName)
SELECT 'TBAG'
END

Related

using FUNCTION -SQL Server query to find the current post of the employee [duplicate]

This question already has answers here:
Retrieving last record in each group from database - SQL Server 2005/2008
(2 answers)
Closed 2 years ago.
Can you tell how to find the last updated post of the employee from the table. Two tables :Employee and EmployeeDetails. Employee fields are: EmployeeID ,EmployeeName EmployeeDetails fields are: EmployeeID, Designation, PromotionDate.
How to find the current Designation of an employee if we give an EmployeeID. Using function. I want to create a simple function to get the Designation according to the current Designation (Latest PromotionDate ) using the EmployeeID, then join with Employee table.
DROP TABLE IF EXISTS Employee
CREATE TABLE Employee
(
EmployeeID INT NOT NULL PRIMARY KEY IDENTITY(1000,1),
EmployeeName VARCHAR(25)
)
INSERT INTO Employee VALUES('AAA');
INSERT INTO Employee VALUES('LAAA');
INSERT INTO Employee VALUES('RSSS');
INSERT INTO Employee VALUES('SEEE');
INSERT INTO Employee VALUES('CFFF');
INSERT INTO Employee VALUES('SEEEW');
INSERT INTO Employee VALUES('MCCC');
INSERT INTO Employee VALUES('DERR');
INSERT INTO Employee VALUES('DERR');
INSERT INTO Employee VALUES('DERW');
SELECT * FROM Employee
DROP TABLE EmployeeDetails
CREATE TABLE EmployeeDetails
(
EmployeeID INT FOREIGN KEY REFERENCES Employee(EmployeeID),
Designation VARCHAR(25),
PromotionDate Date
)
INSERT INTO EmployeeDetails VALUES(1000,'www','2020-11-20');
INSERT INTO EmployeeDetails VALUES(1000,'qqq','2020-01-23');
INSERT INTO EmployeeDetails VALUES(1009,'qqq','2020-09-20');
SELECT * FROM EmployeeDetails
SELECT
E.EmployeeID,
E.EmployeeName,
ED.Designation, ED.PromotionDate
FROM
Employee E
JOIN
EmployeeDetails ED ON E.EmployeeID = ED.EmployeeID
I wrote a function for this, but I don't know how to incorporate it with the query:
CREATE FUNCTION GetOnlyTheCurrentPost
( #EmpID INT)
RETURNS DATE
AS
BEGIN
DECLARE #PromoDate DATE
SELECT #PromoDate= MAX(PromotionDate)
FROM EmployeeDetails
WHERE EmployeeID = #EmpID
RETURN(#PromoDate)
END
I changed the function like this as below
ALTER FUNCTION [dbo].[GetOnlyTheCurrentPost]
( #PromoDate DATE)
RETURNS DATE
AS
BEGIN
SELECT #PromoDate= MAX(PromotionDate)
FROM EmployeeDetails
RETURN(#PromoDate)
END
SELECT
E.EmployeeID,
ED.Designation,[dbo].[GetOnlyTheCurrentPost](ED.PromotionDate) AS LatestPost
FROM
Employee E
JOIN
EmployeeDetails ED
ON E.EmployeeID = ED.EmployeeID
This will show all the records not only the latest post but also every records.
Again, I changed my function. I want to get the current Designation, if i give the EmployeeID Like, SELECT [dbo].[GetOnlyTheCurrentDesignation](1011). Output should be printed according to the given corresponding EmployeeID Output : ProjectManager
ALTER FUNCTION GetOnlyTheCurrentDesignation
(#EmpID INT)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #Designation VARCHAR(25)
SELECT #Designation=Designation, MAX(PromotionDate)
FROM EmployeeDetails
WHERE EmployeeID = #EmpID
RETURN(#Designation)
END
Please tell me a solution to fix this
Try something like this:
SELECT
E.EmployeeID,
E.EmployeeName,
ED.Designation, ED.PromotionDate
FROM
Employee E
JOIN
(SELECT * FROM EmployeeDetails ED2
WHERE PromotionDate = (SELECT MAX(PromotionDate)
FROM EmployeeDetails
WHERE EmployeeID = ED2.EmployeeID)) ED
ON E.EmployeeID = ED.EmployeeID

How can insert value by selecting from another

I have three tables. table1 for insert data and table2, table3 for selecting data.
table1:
int id,
varchar name,
varchar gender,
varchar category,
table2:
int id,
varchar gender,
table3:
int id,
varchar category,
According to these tables, i'm using stored procedure as below:
Create procedure ABC
(
#id varchar(10),
#name varchar(11),
#gender varchar(10),
#category varchar(10)
)
As
begin
Insert into table1(id, name, gender, category) select #id, #name, g.id, c.id from gender g, category c where g.gender=#gender and c.category=#category
end
Now, using this if gender or category is empty then data is not inserting. Please tell me where i'm wrong and tell best query to insert data using select query. Please help me to solve the problem. Thanks
You are using and in where clause which means only if gender = #gender then it is selecting any record.
Create procedure ABC
(
#id int, ----- change this to int since id is int type in your table
#name varchar(11),
#gender varchar(10)='',
#category varchar(10)=''
)
As
begin
Insert into table1(id, name, gender, category)
select #id, #name, g.id, c.id from gender g, category c
where (g.gender=#gender or isnull(#gender,'')='') and (c.category=#category or isnull(#category,'')='')
end
Although you may use this approach. But since you want to insert id of gender and category column in your table, then on passing null or blank value what is your expected id to be put in your record.
It is better if you first check gender and category value in your respected table and if record not found then insert it in your table and then save its corresponding id in your final table.

How to count records in SQL

Edit: Schema taken/extrapolated from comment below
create table #employees
(
Emp_ID int,
Name varchar(50),
Dept_ID int,
);
create table #departments
(
Dept_ID int,
Dept_Name varchar(50)
);
How do I count the number of employees from table employees that work in each department in table departments and include all departments that have no employees working in them.
Welcome to SO.
This problem is quite simple to solve. The steps would be as follows:
Join the Departments table to the Employees table on the Dept_ID column.
SELECT the Dept_ID and Count() and GROUP BY the Dept_ID field.
In order to return Departments without employees you need to LEFT JOIN this aggregation to the Departments table on the Dept_ID column.
In order to return the value of 0 for departments without employees, use the ISNULL() function.
Please see the below sample script using your schema. Note that this script is written in T-SQL, as you did not mention your server type.
create table #employees
(
Emp_ID int,
Name varchar(50),
Dept_ID int,
);
create table #departments
(
Dept_ID int,
Dept_Name varchar(50)
);
insert into #employees
select 1, 'Pim', 1
union all
select 2, 'Salma', 2;
insert into #departments
select 1, 'IT'
union all
select 2, 'Marketing'
union all
select 3, 'Design'
select
d1.Dept_Name
,isnull(d2.EmployeeCount, 0) as EmployeeCount
from
#departments d1
left join
(
select
d.Dept_ID
,count(e.Dept_ID) as EmployeeCount
from
#departments d
join
#employees e
on e.Dept_ID = d.Dept_ID
group by
d.Dept_ID
)
d2
on d2.Dept_ID = d1.Dept_ID
drop table #employees
drop table #departments
As you have supplied no data please try below and see if this works for you
Create the tables, I don't know if this is similar to your table structure
CREATE TABLE tbl_EMPLOYEES (Empl_Name nvarchar(20), Dept nvarchar(15))
CREATE TABLE tbl_DEPARTMENT (Dept nvarchar(15))
Populate these tables
INSERT INTO tbl_EMPLOYEES Values ('James', 'Finance')
INSERT INTO tbl_EMPLOYEES Values ('Tim', 'HR')
INSERT INTO tbl_EMPLOYEES Values ('Sally', 'Finance')
INSERT INTO tbl_EMPLOYEES Values ('Bob', 'Sales')
INSERT INTO tbl_EMPLOYEES Values ('Sam', 'HR')
INSERT INTO tbl_EMPLOYEES Values ('James', 'Finance')
INSERT INTO tbl_DEPARTMENT Values ('Finance')
INSERT INTO tbl_DEPARTMENT Values ('HR')
INSERT INTO tbl_DEPARTMENT Values ('Sales')
INSERT INTO tbl_DEPARTMENT Values ('IT')
This query will give you the number of people in each department
SELECT Dept, Count(Dept) AS Count
FROM
(
SELECT Dept
FROM tbl_EMPLOYEES
) AS Blah_Blah
GROUP BY Dept

How to write dynamic insert statement in sql server?

I have a Student table and Department table.
Student Table contains Three columns
StudentId | DeptId | StudentName
Department Table contains
DeptId | DeptName
It may be the case that DeptTable sometimes doesnot exists. That is I am deploying script with two scenarios sometimes with department and sometimes without. In the case without department , departmentId will not be there in student table
So when Department table exists I have to insert value of DeptId otherwise I have to write insert statement without departmentId
IF (EXISTS(
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'Department'
AND column_name = 'DeptId'
))
DECLARE #DeptId UNIQUEIDENTIFIER;
SET #DeptId = Select DeptId From Department Where DeptName = 'Computer'
INSERT INTO Student ([DeptId], [StudentName])
VALUES (#DeptId, 'TBAG')
But as DeptId column sometimes not present I need to create dynamic Sql.
So I created Select statement
DECLARE #sqlCommand nvarchar(1000)
DECLARE #DeptName varchar(75)
declare #DeptId uniqueIdentifier
SET #DeptName = 'Computer'
SET #sqlCommand = 'SELECT #dept=DeptId FROM customers WHERE DeptName = #DeptName'
EXECUTE sp_executesql #sqlCommand, N'#DeptName varchar(50),#dept uniqueIdentifier OUTPUT', #DeptName = #DeptName, #dept=#DeptId OUTPUT
But how to write Insert statement I am not getting
CREATE TABLE dbo.Student
(
DeptId UNIQUEIDENTIFIER,
StudentName VARCHAR(20)
)
GO
DECLARE #DeptId UNIQUEIDENTIFIER
IF COL_LENGTH('dbo.Department', 'DeptId') IS NOT NULL BEGIN
SELECT #DeptId = DeptId
FROM dbo.Department
WHERE DeptName = 'Computer'
END
INSERT INTO dbo.Student(DeptId, StudentName)
SELECT #DeptId /* null is when DeptId is not exists */, 'TBAG'
Output -
(1 row(s) affected)
As per my understanding you want to prepare dynamic insert statement for student table with two cases (with deptid or without deptid)
Please refer the code below.
DECLARE #STUDENTID INT='',--MENTION YOUR STUDENT ID VALUE AND USE THE SAME IN THE ELSE PART COMMENT OUT IF IT HAS IDENTITY
#STUDENTNAME VARCHAR(100)=''--MENTION YOUR STUDENT NAME
IF Col_length('dbo.Student', 'DeptId') IS NOT NULL
BEGIN
INSERT INTO dbo.Student
(DeptId,
StudentName)
SELECT DeptId,
'TBAG'
FROM dbo.Department
WHERE DeptName = 'Computer'
END
ELSE
BEGIN
INSERT INTO dbo.Student
(StudentName)
SELECT #STUDENTNAME
END

Generating HierarchyID

I would like to insert the hierarchyId like this
/ - CEO (Root)
/1/ - Purchase Manager
/1/1/ - Purchase Executive
/2/ - Sales Manager
/2/1/ - Sales Executive
This is what the hierarchy i would like to use, is it right one, if so how can i do this, can any one give me some code snippet.
I came across this question while searching for information on the hierarchyid data type, and thought it would be interesting for anyone else coming after me to also see code to insert hierarchyids as per the question.
I do not claim that these are the only ways to insert hierarchyids, but hopefully it will help those who, like me, have no previous experience working with this data type.
Using this table,
create table OrgChart
(
Position hierarchyid,
Title nvarchar(50)
)
you can use Parse to directly insert the hierarchyids using the string paths:
insert into OrgChart(Position, Title)
values (hierarchyid::Parse('/'), 'CEO'),
(hierarchyid::Parse('/1/'), 'Purchase Manager'),
(hierarchyid::Parse('/1/1/'), 'Purchase Executive'),
(hierarchyid::Parse('/2/'), 'Sales Manager'),
(hierarchyid::Parse('/2/1/'), 'Sales Executive')
and use the following query to check the table
select Position.ToString(), * from OrgChart
You can also use the hierarchyid data type methods GetRoot and GetDescendant to build the hierarchy. I found this method to be more cumbersome, but I suppose using these methods is necessary if you are programmatically managing the hierarchy.
declare #root hierarchyid,
#id hierarchyid
set #root = hierarchyid::GetRoot()
insert into OrgChart(Position, Title) values (#root, 'CEO')
set #id = #root.GetDescendant(null, null)
insert into OrgChart(Position, Title) values (#id, 'Purchase Manager')
set #id = #root.GetDescendant(#id, null)
insert into OrgChart(Position, Title) values (#id, 'Sales Manager')
select #id = Position.GetDescendant(null, null) from OrgChart where Title = 'Purchase Manager'
insert into OrgChart(Position, Title) values (#id, 'Purchase Executive')
select #id = Position.GetDescendant(null, null) from OrgChart where Title = 'Sales Manager'
insert into OrgChart(Position, Title) values (#id, 'Sales Executive')
Definitely check out the links provided in the other answer, but hopefully having this code to try out will help as well.
Suppose that you have a table schema with a self-join (as shown below) and that the ManagerID of your CEO is NULL.
CREATE TABLE Employee
(
EmployeeID int NOT NULL IDENTITY(1,1) PRIMARY KEY
, JobTitle nvarchar(50) NOT NULL
, FirstName nvarchar(50) NOT NULL
, LastName nvarchar(50)
, ManagerID int
)
ALTER TABLE dbo.Employee ADD CONSTRAINT
FK_Employee_Employee FOREIGN KEY
(
ManagerID
) REFERENCES dbo.Employee
(
EmployeeID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
INSERT INTO Employee(JobTitle, FirstName, LastName, ManagerID)
Values ('Executive', 'Supreme', 'Leader', NULL)
INSERT INTO Employee(JobTitle, FirstName, LastName, ManagerID)
Values ('Manger', 'Boss', 'Man', 1)
INSERT INTO Employee(JobTitle, FirstName, LastName, ManagerID)
Values ('Minion', 'Bob', 'Minion', 2)
INSERT INTO Employee(JobTitle, FirstName, LastName, ManagerID)
Values ('Minion', 'Joe', 'Minion', 2)
GO
You can auto-generate an initial set of hierarchyid values using the following recursive CTE:
;WITH EmployeeHierarchy (
EmployeeHierarchyID
, EmployeeID
, JobTitle
, LastName
, FirstName
, ManagerID
)
AS (
SELECT HIERARCHYID::GetRoot() AS EmployeeHierarchyID
, EmployeeID
, JobTitle
, LastName
, FirstName
, ManagerID
FROM Employee
WHERE ManagerID IS NULL
UNION ALL
SELECT HIERARCHYID::Parse(Manager.EmployeeHierarchyID.ToString() + (
CONVERT(VARCHAR(20), ROW_NUMBER() OVER (
ORDER BY DirectReport.EmployeeID
))
) + '/') AS EmployeeHierarchy
, DirectReport.EmployeeID
, DirectReport.JobTitle
, DirectReport.LastName
, DirectReport.FirstName
, DirectReport.ManagerID
FROM EmployeeHierarchy AS Manager
INNER JOIN Employee AS DirectReport
ON Manager.EmployeeID = DirectReport.ManagerID
)
SELECT EmployeeHierarchyID
, EmployeeID
, JobTitle
, LastName
, FirstName
, ManagerID
INTO #EmployeeHierarchy
FROM EmployeeHierarchy
ORDER BY EmployeeHierarchyID
GO
It then becomes a fairly trivial matter to add a hierarchyid column to the table, add an index on it, and then populate it by joining to the temp table.
ALTER TABLE dbo.Employee ADD
EmployeeHierarchyID hierarchyid NULL
GO
UPDATE Employee
SET Employee.EmployeeHierarchyID = #EmployeeHierarchy.EmployeeHierarchyID
FROM Employee INNER JOIN
#EmployeeHierarchy ON Employee.EmployeeID = #EmployeeHierarchy.EmployeeID
GO
SELECT EmployeeHierarchyID.ToString() AS EmployeeHierarchyIDString, EmployeeID, JobTitle, FirstName, LastName, ManagerID, EmployeeHierarchyID
FROM Employee
GO
However, bear in mind that if you want the hierarchyid data to remain consistent after you add it, there are very specific ways in which it should be maintained.