Compare Column names from 2 diff table in diff db in MS SQL - sql

I am trying to get column names from 2 diff tables in diff db and compare them to see if there is any extra column in any table. They should match exactly. One possible solution could be getting all the column names from both table and dump in a temp table side by side and compare? Pls help.
IF OBJECT_ID('tempdb..#myTable') IS NOT NULL DROP TABLE #myTable
CREATE table #myTable (
table1 varchar(100) null,
table2 varchar(100) null
)
INSERT INTO #myTable (table1)
SELECT name
FROM sys.columns
WHERE object_id = OBJECT_ID('table1')
select * from #mytable
DROP TABLE #mytable

I modified your query to this
IF OBJECT_ID('tempdb..#myTable') IS NOT NULL DROP TABLE #myTable
CREATE table #myTable
(
rowNum int IDENTITY(1,1),
table1 varchar(100) null
)
GO
IF OBJECT_ID('tempdb..#myTable2') IS NOT NULL DROP TABLE #myTable2
CREATE table #myTable2
(
rowNum int IDENTITY(1,1),
table2 varchar(100) null
)
GO
USE database1 --your 1st database name here
GO
INSERT INTO #myTable (table1)
(
SELECT
name
FROM sys.columns
WHERE object_id = OBJECT_ID('Table_1'))
GO
USE database2 -- your 2nd database name here
GO
INSERT INTO #myTable2 (table2)
(
SELECT
name
FROM sys.columns
WHERE object_id = OBJECT_ID('Table_2'))
GO
SELECT table1,table2
FROM #myTable m
FULL OUTER JOIN #myTable2 m2 ON m.rowNum = m2.rowNum
ORDER BY table1,table2
DROP TABLE #mytable
DROP TABLE #mytable2

Related

How to split data in SQL Server table row

I have table of transaction which contains a column transactionId that has values like |H000021|B1|.
I need to make a join with table Category which has a column CategoryID with values like H000021.
I cannot apply join unless data is same.
So I want to split or remove the unnecessary data contained in TransctionId so that I can join both tables.
Kindly help me with the solutions.
Create a computed column with the code only.
Initial scenario:
create table Transactions
(
transactionId varchar(12) primary key,
whatever varchar(100)
)
create table Category
(
transactionId varchar(7) primary key,
name varchar(100)
)
insert into Transactions
select'|H000021|B1|', 'Anything'
insert into Category
select 'H000021', 'A category'
Add computed column:
alter table Transactions add transactionId_code as substring(transactionid, 2, 7) persisted
Join using the new computed column:
select *
from Transactions t
inner join Category c on t.transactionId_code = c.transactionId
Get a straighforward query plan:
You should fix your data so the columns are the same. But sometimes we are stuck with other people's bad design decisions. In particular, the transaction data should contain a column for the category -- even if the category is part of the id.
In any case:
select . . .
from transaction t join
category c
on transactionid like '|' + categoryid + |%';
Or if the category id is always 7 characters:
select . . .
from transaction t join
category c
on categoryid = substring(transactionid, 2, 7)
You can do this using query :
CREATE TABLE #MyTable
(PrimaryKey int PRIMARY KEY,
KeyTransacFull varchar(50)
);
GO
CREATE TABLE #MyTransaction
(PrimaryKey int PRIMARY KEY,
KeyTransac varchar(50)
);
GO
INSERT INTO #MyTable
SELECT 1, '|H000021|B1|'
INSERT INTO #MyTable
SELECT 2, '|H000021|B1|'
INSERT INTO #MyTransaction
SELECT 1, 'H000021'
SELECT * FROM #MyTable
SELECT * FROM #MyTransaction
SELECT *
FROM #MyTable
JOIN #MyTransaction ON KeyTransacFull LIKE '|'+KeyTransac+'|%'
DROP TABLE #MyTable
DROP TABLE #MyTransaction

Inserting a Row of Default Values into a Temporary Table

I'm attempting to select a row of default values from a table. However, I don't want to create a new row in my original table. My original table has non-null default values (all blanks or zeros) defined for all columns (except for the one unique identifier). I begin by creating the temporary table:
SELECT
TOP 0 *
INTO
#Table
FROM
Database.dbo.Table
Then I examine the empty table:
SELECT
*
FROM
#Table
Everything looks fine so far. There are no rows, but I can see all the columns from my original table. Then, I attempt to insert a single row into the table with default values for all the columns:
INSERT INTO
#Table
DEFAULT VALUES
Rather than success, I get the following error:
Cannot insert the value NULL into column 'Column',
table 'tempdb.dbo.#Table___0001A';
column does not allow nulls. INSERT fails.
I next tried to insert a row with just one field defined.
INSERT INTO
#Table
(Column)
VALUES
('Value')
Same results. It appears that the definitions of the column default values from my original table were not included in the creation of the temporary table. Any suggestions?
When you create a temp table via SELECT ... INTO #Table the temp table gets all columns from the main table, but no constraints or indexes.
Obviously, you can explicitly create temp table with all necessary constraints.
One more option is to actually insert a row into the main table, let the engine populate it with default values, then read inserted values and insert them into the temp table. All this in a transaction. Then rollback the transaction, so that the main table remains as it was.
To make it work you need to use table variable instead of temp table, though, because temp tables participate in transactions as normal tables, but table variables don't. It means that you have to define the table variable in advance, so you need to know what columns your original table has. But, at least, you don't have to know the definition of default constraints.
Also, if your main table has an INDENTITY column, this insert-rollback will create a gap in identity values.
Sample table
CREATE TABLE [dbo].[MainTable](
[Col1] [int] NOT NULL,
[Col2] [nvarchar](50) NOT NULL,
[Col3] [date] NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[MainTable] ADD CONSTRAINT [DF_MainTable_Col1]
DEFAULT ((123)) FOR [Col1]
GO
ALTER TABLE [dbo].[MainTable] ADD CONSTRAINT [DF_MainTable_Col2]
DEFAULT ('qwerty') FOR [Col2]
GO
ALTER TABLE [dbo].[MainTable] ADD CONSTRAINT [DF_MainTable_Col3]
DEFAULT (getdate()) FOR [Col3]
GO
Query
DECLARE #T TABLE (Col1 int, Col2 nvarchar(50), Col3 date);
BEGIN TRANSACTION;
INSERT INTO dbo.MainTable
OUTPUT inserted.Col1, inserted.Col2, inserted.Col3
INTO #T (Col1, Col2, Col3)
DEFAULT VALUES;
ROLLBACK TRANSACTION;
SELECT *
FROM #T;
Result
+------+--------+------------+
| Col1 | Col2 | Col3 |
+------+--------+------------+
| 123 | qwerty | 2017-08-29 |
+------+--------+------------+
You need to create your temp table and include the default definitions in it.
--Check to see if table exists
--If it does, drop it
IF OBJECT_ID('tempdb.dbo.#Table', 'U') IS NOT NULL
DROP TABLE #Table
--Create temp table with default value
CREATE TABLE #Table
(
columnA INT DEFAULT (1),
columnB INT DEFAULT (2),
columnC INT DEFAULT (3)
)
--Insert a row of default values
INSERT INTO
#Table
DEFAULT VALUES
--See it
SELECT *
FROM #Table
--Drop temp table after you are done
DROP TABLE #Table
Build your row from the temptdb catalog?
SELECT c.name AS 'Colunmn'
, TYPE_NAME(c.user_type_id) AS 'Type'
, CASE c.is_nullable WHEN 0 THEN 'No Nulls'
ELSE '' END AS 'Nullable'
, CASE c.default_object_id WHEN 0 THEN ''
ELSE 'Y' END AS 'Has_Default'
, dft.definition as Default_Value
, CASE ISNULL(c.max_length, -1) WHEN -1 THEN 'Variable'
ELSE CAST(c.max_length AS VARCHAR) END AS 'Length'
, ISNULL('['+OBJECT_NAME(fkc.referenced_object_id)+'].['+Cref.name+']', ' ') AS ForeignKeyInto
FROM tempdb.sys.tables t
JOIN tempdb.sys.columns c ON t.object_id = c.object_id
LEFT JOIN tempdb.sys.foreign_key_columns FKC ON c.object_id = fkc.Parent_object_id
AND fkc.parent_column_id = c.column_id
LEFT JOIN tempdb.sys.columns cref ON fkc.referenced_column_id = cref.column_id
AND fkc.referenced_object_id = cref.object_id
left join tempdb.sys.default_constraints dft on c.default_object_id = dft.object_id
WHERE t.name like '#temp%'
ORDER BY t.name
, c.name;

Fill automatic data in second table when insert data in one table

I have two table Table1 and Table2 and structure of table as
Table1
Primary Key | Name
Table2
Primary Key | Table1_Id_pk | Status - true/false value
When I insert data into Table2 I want to automatically transfer that data in table1 from Table2 which have Status false.
You can create AFTER INSERT trigger:
CREATE TRIGGER DataMigration
ON Table2
AFTER INSERT
AS
BEGIN
INSERT INTO Table1
SELECT *
FROM TAble2
WHERe Status = 'false'
END
GO
Check this example, use ##identity to get inserted row-id and use that id for child table.
declare #t1 table (pk int identity(1,1) not null , name varchar(50) )
declare #t2 table (pk int identity(1,1) not null , t1pk int, status bit )
declare #new_table1Id int
insert into #t1 values( 'ajay')
set #new_table1Id = ##IDENTITY -This gives you last inserted id of #t1
insert into #t2 values( #new_table1Id , 0)
select * from #t1
select * from #t2
##IDENTITY official documentation

Showing data as a column name

I have three tables. I called them as Table A,Table B,Table C.
And I have desired view which I want to get.
Table A
Aid RegNum BID Value
2CE7D0A7 2000000 D5981DFC OFFCRO
9D3C13AA 2000000 C58566C5 YCH - from
9DDB90C4 2000000 812E9E75 Y
Table B is connected to Table A by Table B's foreign key in Table A
Table B
BID Label ColumnName Order
D5981DFC Offered/Change Role StatusChangeCode 0
C58566C5 Offered/Role Change Comments StatusChangeComments 1
812E9E75 Assessed StatusChangeAssessed 2
Table C has foreign key in Table A as well. Reg Num. Reg num is primary key in Table C
Table C
Name Surname RegNum
Etibar Hasanov 2000000
As you see there are column's names which are datas in Table B
DesiredView
Name Surname RegNum StatusChangeCode StatusChangeComments StatusChangeAssessed
Etibar Hasanov 2000000 OFFCRO YCH - from Y
You can achieve this by using PIVOT table. Try something like this,
Create Table TableA(Aid varchar(50), RegNum int, BID Varchar(20), Value varchar(50))
insert into TableA values
('2CE7D0A7', 2000000, 'D5981DFC', 'OFFCRO'),
('9D3C13AA', 2000000, 'C58566C5', 'YCH - from' ),
('9DDB90C4', 2000000, '812E9E75', 'Y')
create Table TableB(BID Varchar(20), Label Varchar(50), ColumnName
Varchar(50), [Order] int)
insert into TableB values
('D5981DFC', 'Offered/Change Role', 'StatusChangeCode', 0),
('C58566C5', 'Offered/Role Change Comments', 'StatusChangeComments', 1),
('812E9E75', 'Assessed', 'StatusChangeAssessed', 2)
Create Table TableC (Name Varchar(20), Surname Varchar(20), RegNum int)
insert into TableC values
('Etibar', 'Hasanov', 2000000)
SELECT *
FROM (
SELECT
Name, SurName, C.RegNum, Value, B.ColumnName
FROM TableC C
JOIN TableA A ON C.RegNum = A.RegNum
JOIN TableB B on B.BID = A.BID
) AS Source
PIVOT
(
MAX(Value)
FOR [ColumnName]
in ( [StatusChangeCode], [StatusChangeComments], [StatusChangeAssessed] )
)AS Pvot
Sql Fiddle Demo
If you are using SQL server 2005, according to Microsoft Technet,
When PIVOT and UNPIVOT are used against databases that are upgraded to
SQL Server 2005 or later, the compatibility level of the database must
be set to 90 or higher.
I first selected columns names. In this table it brings [StatusChangeAssessed],[StatusChangeCode],[StatusChangeComments] . Then in the next query I setted #col ( column names ).
declare #nregnumber nvarchar(10)='2000000';
DECLARE #cols AS NVARCHAR(MAX), #runningquery as nvarchar(max);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(rn)
from
(
select columnname rn from tableb where exists ( select * from tablea where tablea.bid=tableb.bid and regnum=#nregnumber)
) t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set #runningquery='
SELECT *
FROM (
SELECT
Name, SurName, C.RegNum, Value, B.ColumnName
FROM TableC C
JOIN TableA A ON C.RegNum = A.RegNum
JOIN TableB B on B.BID = A.BID
) AS Source
PIVOT
(
MAX(Value)
FOR [ColumnName]
in ( '+#cols+')
)AS Pvot'
exec (#runningquery)
Special thanks to Selva.

Prevent insertion of duplicates

I have a table with columns CompanyID, EmployeeCode. EmployeeCode is unique and CompanyID can be repeated. So we can keep a list of employees in Google, Apple etc.
I want a way to ensure that the same employee cannot be added if he/she is already in the database. What would be a good way to do this ? I'd prefer not to create additional columns or tables for this.
Create a UNIQUE constraint on the column where you want to prevent duplicates:
CREATE UNIQUE INDEX [IX_YourTableName_EmployeeCode] ON [YourTableName] (EmployeeCode)
Try this..
Create table UniqueTable
(
CompanyID int,
EmployeeCode int
)
--Insert dummy data
INSERT INTO UniqueTable(EmployeeCode ,CompanyID ) Values(1,200)
--When are Going to insert duplicate Ecmployeecode '1' then it will not insert data into table
INSERT INTO UniqueTable(EmployeeCode ,CompanyID )
Select 1,200 From UniqueTable t1
Left join UniqueTable t2 on 1=t2.EmployeeCode
WHERE t2.EmployeeCode IS NULL
--We are Going to insert different Ecmployeecode '2' it will insert into table
INSERT INTO UniqueTable(EmployeeCode ,CompanyID )
Select 2,300 From UniqueTable t1
Left join UniqueTable t2 on 2=t2.EmployeeCode
WHERE t2.EmployeeCode IS NULL
Try this
Create PROCEDURE [dbo].[sp_Emp_Insert]
#EmployeeCode nvarchar(50)
As
Begin
if Not Exists (select EmployeeCode from YOUR_TABlE where EmployeeCode =#EmployeeCode )
Begin
Insert QUERY
End
else
Return 0
End
End