SQL Server : openquery insert linked server - sql-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;

Related

SQL Server view metadata information

I have a table as below:
create table employee_details
(
id int,
name varchar(10)
)
And this is a view based on employee_details:
create view vw_empl_details
as
select id as emp_id, name as emp_name
from employee_details
I want to know which system table keeps track of column wise information for above condition..
id-> emp_id
name-> emp_name
we have below 2 tables to keep track of tables but not sure columnwise information is available in SQL Server
select * from [INFORMATION_SCHEMA].[VIEW_COLUMN_USAGE]
select * from [INFORMATION_SCHEMA].VIEW_TABLE_USAGE
I guess you want (sys.sql_modules.definition):
SELECT *
FROM sys.sql_modules
WHERE OBJECT_ID = OBJECT_ID('vw_empl_details');
Rextester.com
Mapping only when there is simple aliasing:
SELECT column_ordinal, name, source_table, source_column
FROM sys.dm_exec_describe_first_result_set
('SELECT * FROM vw_empl_details', NULL, 1);
Output:
Rextester Demo2

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

Pass Column value to parameter in Dataflow task SSIS

I have a SQL table TABLE1 which has columns ID and LastModifiedDate.Now I have one oracle query SELECT * From Table where NEWID =? where parameter will be the value from ID column from TABLE1 and I need to insert these records into a destination table on a SQL Server.Please advise the best approach for this.I am using SQL 2008.
Where #Id will be parameter
INSERT INTO DESTINATIONTABLE
SELECT *
FROM TABLE
WHERE NEWID IN(SELECT ID From Table1 WHERE ID=#ID)
or if you want to specify the columns you could use
INSERT INTO DESTINATIONTABLE(Col1,Col2)
SELECT Col1,Col2
FROM TABLE
WHERE NEWID IN(SELECT ID From Table1 WHERE ID=#ID)

SELECT INSERT INTO

Is it possible to insert data from select statement into a a dynamically created table? I will not know how many columns are there in select statement until I run the query. It has to create the appropriate number of columns at run time.
Thank you,
Smith
Just use the SELECT INTO syntax:
SELECT *
INTO NewTable
FROM MyTable
WHERE ...
The new table NewTable will be created with the same columns as your select statement.
You can use a CTAS pattern for this
USE AdventureWorks
GO
----Create new table and insert into table using SELECT INSERT
SELECT FirstName, LastName
INTO TestTable
FROM Person.Contact
WHERE EmailPromotion = 2
----Verify that Data in TestTable
SELECT FirstName, LastName
FROM TestTable
----Clean Up Database
DROP TABLE TestTable
GO
Have a look at This Article on CTAS
-- This creates temporary table
select *
into #newtable
from YourTable
select * from #newtable
-- This creates physical table in the DB
select *
into newtable
from YourTable
select * from newtable

a select statement in a transaction against a loopback linked server never stops

In Sql Server 2008 r2, I have a table called Emp, and I'm trying to update some values in a transaction (outer tran), now after the update and before the commit, I began another transaction, in witch i tried to select data from the same table (Emp) but via a loopback linked server.
the tsql look like this:
USE MASTER
GO
EXEC sp_addlinkedserver #server = N'loopback',#srvproduct=N'',#provider = N'SQLNCLI', #datasrc = ##SERVERNAME,#catalog = 'MstrDtl'
GO
EXEC sp_serveroption loopback,N'remote proc transaction promotion','FALSE'
Go
create SYNONYM loopy FOR loopback.MstrDtl.dbo.Emp
use MstrDtl
BEGIN TRAN OuterTran
BEGIN
update table dbo.Emp set Salary = 123456 where Name='abcdx'
BEGIN TRAN InnerTran
select Salary from loopy where Name = 'abcdx'
COMMIT TRAN InnerTran
ROLLBACK TRAN OuterTran
END
so i have two questions:
can i get old values (the affected rows with the update) in the query to loopback inside the InnerTran using this way?
the query never stops, any idea?
To answer your questions:
No, you cannot get the old values in that way; you'll get blocked (see #2) or you'll get the new values.
The reason the query never stops is because you're blocking yourself (technically, you're deadlocking yourself.) Your outer transaction is holding a lock on that row (page actually) and therefore the loopback query is blocked until the update lock is released. You could (but shouldn't) specify WITH (NOLOCK) on your loopback query but that will actually return the updated but uncommitted row.
If you want the OLD values in your query use the OUTPUT clause. http://msdn.microsoft.com/en-us/library/ms177564.aspx
CREATE TABLE #emp
(
id INT IDENTITY PRIMARY KEY CLUSTERED,
empName VARCHAR(255),
salary MONEY
)
go
INSERT INTO #emp(empName, salary)
SELECT 'bill', 5000
UNION ALL
SELECT 'ted', 5000
UNION ALL
SELECT 'cheech', 35000
UNION ALL
SELECT 'chong', 15000
UNION ALL
SELECT 'tango', 70000
UNION ALL
SELECT 'Cash', 200000
GO
DECLARE #oldValues TABLE
(
id INT,
empname VARCHAR(255),
salary money
)
UPDATE #emp SET salary = salary + 500
OUTPUT DELETED.* INTO #oldValues
WHERE empName = 'bill'
SELECT E.empName, E.salary AS NewSalary, O.salary AS OldSalary
FROM #emp E
INNER JOIN #oldValues O
ON E.id = O.id
DROP TABLE #emp

Resources