SQL Server : executing query conditionally - sql-server

I have Employees tables in the database with a column EmpID which was changed to ID. I want to use the same query in both the old and new table and get the same result depending on the condition.
I have tried the following:
IF (COL_LENGTH('Employees', 'EmpID') IS NOT NULL)
SELECT EmpID, NAME, SEX, SALARY
FROM Employees
WHERE EmpID IS NOT NULL
ELSE
SELECT ID, NAME, SEX, SALARY
FROM Employees
WHERE ID IS NOT NULL
But when I run the query in the new table, I get column name EmpID doesn't exist error. Any help is appreciated!

You can do this without dynamic SQL using this approach.
SELECT ISNULL(CA.ID, CA.EmpID) AS ID,
CA.NAME,
CA.SEX,
CA.SALARY
FROM (VALUES(NULL, NULL)) V(ID, EmpID)
CROSS APPLY (SELECT ID, /*Resolved from Employees if present or "V" otherwise */
EmpID, /*Resolved from Employees if present or "V" otherwise */
NAME,
SEX,
SALARY
FROM Employees) CA
WHERE ISNULL(CA.ID, CA.EmpID) IS NOT NULL;
Demo

The issue is the compile stage versus the execution stage. The code is initially compiled, where the tables and columns are validated.
Your problem is that the column doesn't exist, so you are getting a compile failure.
You can fix this using dynamic SQL:
DECLARE #sql NVARCHAR(max);
IF (COL_LENGTH('Employees', 'EmpID') IS NOT NULL)
SET #sql = N'
Select EmpID, NAME, SEX, SALARY
From Employees
Where EmpID IS NOT NULL'
ELSE
SET #sql = N'
Select ID, NAME, SEX, SALARY
From Employees
Where ID IS NOT NULL'
EXEC sp_executesql #sql;

Related

Sql Select query on select query result

I am trying to (select)query inside the previous (select)query from same table.
I've tried this below;
CREATE PROCEDURE dbo.strprcReturnEmpDetails(#EmpID VARCHAR(25))
AS
SELECT [Name],
Role,
Email,
Department,
ReportingAuthority,
DomainID,
ReportsTo,
(
SELECT DISTINCT
EmpID
FROM Login
WHERE [Name] = ReportsTo
) AS approverEmpid
FROM Login
WHERE EmpID = 288;
SET NOCOUNT ON;
RETURN;
I believe you just miss the aliases in the subquery to make it work. Your subquery returns more than one value, you need to make it a dependent subquery as follows:
SELECT [Name], Role, Email, Department, ReportingAuthority,DomainID,ReportsTo,
(
select distinct EmpID
from Login l2
where l2.Name = l1.ReportsTo
) as approverEmpid
FROM Login l1
WHERE EmpID=288
This should work if Name in Login table is unique.

Updating and Inserting to 2 different tables from the Same package

I have 2 tables called Customer and ChangeLog. having the following structure
Customer table
ChangeLog Table
My Requirement is that
I need an SSIS Package that will read the record from another table with the same structure as CustomerTable and then compare the rows on both tables. If a change in any record is found it updates the records in the customer table as well as put an entry in the ChangeLog saying which column was updated.
So when a change is found in any of the columns I need to do the following
Update the Coresposing record in the Customer Table
Insert a new row into the ChangeLog
There won't be an Insert to the Customer Table. There will be only updates
Is there any single Task in SSIS that I can use to do both the update as well as an insert to these different tables ? or else what is the quickest and efficient way to achieve this in SSIS?
Any help is much appreciated
No there is no single SSIS task made to do this. I wouldn't use SSIS for this at all. Put the logic in either a stored procedure or trigger. If you have to use SSIS for some reason, then have SSIS call the stored procedure, or UPDATE the table and let the trigger fire.
This here is better than a SSIS packages since you can use a trigger to detect your row changes, and even the values.
Try my example you can just C/P into management studio. When you update on Sample_Table you will have changes rows and which column in your table.
So what you can do is. Keep your lookup logic in SSIS (if you want something in SSIS) - Updated the Table based on matches in lookup
When these updates happend your trigger will be fired and update the rows that have changed.
Alternative you can create your lookup in a t-sql script and do an ordinary update when custid=custid instead its just as easy. But thats up to you.
EDITED
-- -------------------- Setup tables and some initial data --------------------
CREATE TABLE dbo.Sample_Table (ContactID int, Forename varchar(100), Surname varchar(100), Extn varchar(16), Email varchar(100), Age int );
INSERT INTO Sample_Table VALUES (1,'Bob','Smith','2295','bs#example.com',24);
INSERT INTO Sample_Table VALUES (2,'Alice','Brown','2255','ab#example.com',32);
INSERT INTO Sample_Table VALUES (3,'Reg','Jones','2280','rj#example.com',19);
INSERT INTO Sample_Table VALUES (4,'Mary','Doe','2216','md#example.com',28);
INSERT INTO Sample_Table VALUES (5,'Peter','Nash','2214','pn#example.com',25);
CREATE TABLE dbo.Sample_Table_Changes (ContactID int, FieldName sysname, FieldValueWas sql_variant, FieldValueIs sql_variant, modified datetime default (GETDATE()));
GO
-- -------------------- Create trigger --------------------
CREATE TRIGGER TriggerName ON dbo.Sample_Table FOR DELETE, INSERT, UPDATE AS
BEGIN
SET NOCOUNT ON;
--Unpivot deleted
WITH deleted_unpvt AS (
SELECT ContactID, FieldName, FieldValue
FROM
(SELECT ContactID
, cast(Forename as sql_variant) Forename
, cast(Surname as sql_variant) Surname
, cast(Extn as sql_variant) Extn
, cast(Email as sql_variant) Email
, cast(Age as sql_variant) Age
FROM deleted) p
UNPIVOT
(FieldValue FOR FieldName IN
(Forename, Surname, Extn, Email, Age)
) AS deleted_unpvt
),
--Unpivot inserted
inserted_unpvt AS (
SELECT ContactID, FieldName, FieldValue
FROM
(SELECT ContactID
, cast(Forename as sql_variant) Forename
, cast(Surname as sql_variant) Surname
, cast(Extn as sql_variant) Extn
, cast(Email as sql_variant) Email
, cast(Age as sql_variant) Age
FROM inserted) p
UNPIVOT
(FieldValue FOR FieldName IN
(Forename, Surname, Extn, Email, Age)
) AS inserted_unpvt
)
--Join them together and show what's changed
INSERT INTO Sample_Table_Changes (ContactID, FieldName, FieldValueWas, FieldValueIs)
SELECT Coalesce (D.ContactID, I.ContactID) ContactID
, Coalesce (D.FieldName, I.FieldName) FieldName
, D.FieldValue as FieldValueWas
, I.FieldValue AS FieldValueIs
FROM
deleted_unpvt d
FULL OUTER JOIN
inserted_unpvt i
on D.ContactID = I.ContactID
AND D.FieldName = I.FieldName
WHERE
D.FieldValue <> I.FieldValue --Changes
OR (D.FieldValue IS NOT NULL AND I.FieldValue IS NULL) -- Deletions
OR (D.FieldValue IS NULL AND I.FieldValue IS NOT NULL) -- Insertions
END
GO
-- -------------------- Try some changes --------------------
UPDATE Sample_Table SET age = age+1;
/*UPDATE Sample_Table SET Extn = '5'+Extn where Extn Like '221_';
DELETE FROM Sample_Table WHERE ContactID = 3;
INSERT INTO Sample_Table VALUES (6,'Stephen','Turner','2299','st#example.com',25);
UPDATE Sample_Table SET ContactID = 7 where ContactID = 4; --this will be shown as a delete and an insert
-- -------------------- See the results --------------------
SELECT *, SQL_VARIANT_PROPERTY(FieldValueWas, 'BaseType') FieldBaseType, SQL_VARIANT_PROPERTY(FieldValueWas, 'MaxLength') FieldMaxLength from Sample_Table_Changes;
-- -------------------- Cleanup --------------------
DROP TABLE dbo.Sample_Table; DROP TABLE dbo.Sample_Table_Changes;*/
select * from dbo.sample_table_changes

How to insert data into another table retrieved from Pivot select statement and containing dynamic columns?

Here's my query ,
DECLARE #BranchAsColumn nvarchar(max) -- it may contain branchesName sepereated by comma(,) using as dynamic column, and it may vary e.g. #ABC,#LMN,#XYZ
DECLARE #Branches nvarchar(max) -- it may contain branchesName sepereated by comma(,) using for filter condition, and it may vary e.g. ABC,LMN,XYZ
EXEC('Select CompanyID,Company,Category,SubCategory,Months,'+#BranchAsColumn+'
From
( Select
BranchID,
Branch,
CompanyID,
Company,
Months,
Department,
Amount
From #Data
)P
PIVOT
(
SUM(Amount)
For Branch in ('+#Branches +')
) As Pivottable')
What ever result I will get here I just wanted to insert retrieved data into Another TABLE, so please anyone here help me to get the perfect solution.
Try this out:
EXEC('Select CompanyID,Company,Category,SubCategory,Months,'+#BranchAsColumn+'
INTO ##MyTable
From ( Select
BranchID, Branch,
CompanyID,
Company,
Months, Department,
Amount
From #Data )P PIVOT ( SUM(Amount) For Branch in ('+#Branches +') ) As Pivottable')
-- test results
SELECT * FROM ##MyTable

SQL Server collate error in query

I've looked all over for help on this but nothing seems to be working.
I have the following statement in an SP that fails with the collate error each time:
INSERT INTO #TableR (id, email, forename, Age, gender)
SELECT TOP 1 #TEMPMDUK.id AS [id], email, forename, Age, gender
FROM #TEMPMDUK
WHERE SUBSTRING(postcode, 0, (CHARINDEX(' ', postcode, 0)+2)) in (select Postcode from LiveTable)
and not #TEMPMDUK.ID in (SELECT id FROM #Excludelist)
and #TEMPMDUK.ID in (SELECT id FROM #Includelist)
ORDER BY NEWID()
It only started to happen after we added the following clause to the statement:
WHERE SUBSTRING(postcode, 0, (CHARINDEX(' ', postcode, 0)+2)) in (select Postcode from LiveTable)
If we run this as a clause in a select statement everything is fine but when we put it into the INSERT statement in the SP it breaks.
Any help to resolve this would be much appreciated, thanks.
I don`t know your table structures but it seems that you have different collations in columns. Try playing with
SELECT TOP 1 #TEMPMDUK.id AS [id], email COLLATE Latin1_General_CI_AS, forename, Age, gender
Or
SELECT TOP 1 #TEMPMDUK.id AS [id], email COLLATE SQL_Latin1_General_CP1_CI_AS, forename, Age, gender

SQL Server : openquery insert linked server

How do I insert data into a linked server (oracle) with a condition that a row does not exist?
I want to insert into employee table if employeecode does not exist yet in that table
INSERT INTO OPENQUERY(ORACLEX,
'SELECT EMPCODE, EMPNAME FROM AX.EMPLOYEE') -- I want a where clause here
Select EID, ENAME FROM EMPDATA
You might actually have to read from the table twice
INSERT INTO OPENQUERY(ORACLEX,
'SELECT EMPCODE, EMPNAME FROM AX.EMPLOYEE') -- I want a where clause here
Select D.EID, D.ENAME
FROM EMPDATA D
LEFT JOIN OPENQUERY(ORACLEX,
'SELECT EMPCODE, EMPNAME FROM AX.EMPLOYEE') OQ ON OQ.EMPCODE = D.EID
WHERE QQ.EMPCODE IS NULL;

Resources