how can i create a table just if that table is not exist. in my case, i want to create table with this query :
SELECT *
INTO a
FROM b
that table a in db A and table b in db B. any help?
if not exists (select [name] from sys.tables where [name] = 'a') SELECT *
INTO A.dbo.a
FROM B.dbo.b
you can try this .. its simple one.
You can use the OBJECT_ID function for SQL Server.
IF OBJECT_ID('a') IS NULL
SELECT *
INTO a
FROM b
MySQL, PostgreSQL, Sqlite:
CREATE TABLE IF NOT EXISTS t_exists1
(
c1 TYPE
);
Oracle:
DECLARE cnt NUMBER;
BEGIN
SELECT count(*) INTO cnt FROM all_tables WHERE table_name = 'T_EXISTS1';
IF cnt = 0 THEN
EXECUTE IMMEDIATE 'CREATE TABLE t_exists1
(
c1 TYPE
);';
END IF;
END;
SQL Server:
IF OBJECT_ID('t_exists1', 'U') IS NULL
CREATE TABLE t_exists1
(
c1 TYPE
);
Related
I have temp table name? as an output from a stored procedure and I passed the name of created temp table to another stored procedure as an input parameter.
I want to SELECT Guid from #CalculationGuidTempTableName VARCHAR then insert into #CalcsGuids.
Here is my stored procedure:
CREATE PROCEDURE [dbo].[ret_Reports_ProxyVoucherAccounting]
(#CalculationGuidTempTableName VARCHAR(32))
AS
DECLARE #CalcsGuids TABLE ([Guid] UNIQUEIDENTIFIER PRIMARY KEY)
--INSERT INTO #CalcsGuids (SELECT * FROM + #CalculationGuidTempTableName)
--DROP TABLE #CalculationGuidTempTableName
WITH temp AS
(
SELECT
reference.DetailPureTitle,
reference.DetailCaption,
reference.Nature,
reference.Summarize
FROM
#CalcsGuids calcs
INNER JOIN
ret_vwPayrollCalculationBackPayForReport details ON details.CalculationGuid = calcs.[Guid]
LEFT JOIN
ret_PaymentAllocation payment ON payment.Guid = Details.ItemGuid
INNER JOIN
ret_vwFactorReferences reference ON reference.ItemGuid = Details.ItemGuid
INNER JOIN
ret_PayrollCalculationCommands command ON command.[Guid] = details.CalculationCommandGuid
WHERE
command.Approved = 1 AND command.Deleted = 0
GROUP BY
reference.DetailPureTitle,
reference.DetailCaption,
reference.Nature,
reference.Summarize
)
SELECT
*
FROM
temp
WHERE
PayAmount <> 0 OR
DeductionAmount <> 0 OR
EmployerAmount <> 0
ORDER BY
Nature
Try this :
INSERT INTO #CalcsGuids EXEC ('SELECT * FROM ' + #CalculationGuidTempTableName);
I have two different tables in two different databases. Need to join both the table and get results using query
1) reports - report_id, report_name, description
table reports is present in database 'A'
2) report_owners - report_id, report_owner
table report_owners is present in database 'B'
tried following query for joining the tables but it's throwing error ( Reference to server and/ database is not supported in this version of SQL server).
Query:
select * from [A].[dbo].['reports'] as all_reports
INNER JOIN
select * from [B].[dbo].['report_owners'] as all_owner
ON all_report.report_id = all_owners.report_id
Note: from Database 'A' have access for cross query functionality for database 'B'
Anyone please help me to solve this issue?
You need to use elastic queries to perform cross database queries. See the following example:
Customerinformation (remote db)
CREATE TABLE dbo.CustomerInformation (CustomerID int identity(1,1) , CustomerName nvarchar(255));
DECLARE #i int = 1;
WHILE #i < 20000
BEGIN
INSERT INTO CustomerInformation(CustomerName)
VALUES ('Frodo');
SET #i += 1;
END
On the database that will use the external table
CREATE TABLE OrderInformation(OrderId Int identity(1,1), CustomerId int,Ordervalue int);
SET NOCOUNT ON;
DECLARE #i int = 1;
WHILE #i < 200
BEGIN
INSERT INTO OrderInformation(CustomerId,Ordervalue)
Values (#I,111);
set #i += 1;
END
CREATE EXTERNAL TABLE [dbo].CustomerInformation(
CustomerID [int],
CustomerName nvarchar(255))
WITH
(
DATA_SOURCE = Stackoverflow
);
Query the remote table like this.
SELECT o.OrderId, c.CustomerID, c.CustomerName
FROM OrderInformation o
JOIN CustomerInformation c ON o.CustomerID = c.CustomerID
WHERE o.OrderId = 155
I am trying to check if a table accessed through openquery exists with the following code but it does not work:
IF EXISTS (SELECT * FROM OPENQUERY(SADATABASE, ' select *
from xx_201509_T '
) )
Try something like this:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[xx_201509_T]') AND type in (N'U'))
***DO WHATEVER HERE***
SELECT OBJECT_ID('xx_201509_T', 'U')
if it's NULL, then the table does not exist
EDIT: so in your openquery use it like this:
IF (SELECT objectID FROM OPENQUERY(SADATABASE, 'SELECT OBJECT_ID(''xx_201509_T'', ''U'') as objectID') ) IS NOT NULL
BEGIN
print 'xx_201509_T TABLE EXISTS'
END
When I go to run this query on SQL Server to create an indexed view, an error occurs to remove subqueries and Union
CREATE VIEW [dbo].[view_ToolGroup]
WITH SCHEMABINDING
AS
SELECT
toolGroup.ToolGroupId,toolGroupToTool.ToolId, toolGroupApp.AppId as TGAppId,
purposeToToolGroup.PurposeId as TGPurposeId, TGRole.RoleId as TGRoleId
FROM
[dbo].[toolGroup], [dbo].[purposeToTG], [dbo].[toolGroupToTool],
[dbo].[toolGroupToeApp] as toolGroupApp,
[dbo].[toolGroupToeAppToeRole] as toolGroupAppRole,
[dbo].[eRole] as TGRole
WHERE
toolGroup.ToolGroupId = purposeToToolGroup.ToolGroupId
and toolGroup.ToolGroupId = toolGroupToTool.ToolGroupId
and toolGroup.ToolGroupId = toolGroupApp.ToolGroupId
and toolGroupApp.toolGroupToeApplicationID=toolGroupAppRole.toolGroupToeApplicationID
and toolGroupAppRole.ToolgroupToeApplicationID in
(select ToolgroupToeApplicationID
from [dbo].[ToolgroupToeApplication])
and toolGroupAppRole.RoleId = TGRole.RoleId
UNION
SELECT
toolGroup.ToolGroupId, toolGroup.ToolGroupName,
null, null, null, null, null, null, null, null
FROM
[dbo].[toolGroup], [dbo].[toolGroupToeApplication]
WHERE
toolGroup.ToolGroupId = toolGroupToeApplication.ToolGroupId
and toolGroup.ToolGroupId not in
(select PurposeToToolGroup.ToolGroupId from [dbo].[PurposeToToolGroup])
and toolGroup.ToolGroupId in (select distinct ToolGroupId
from [dbo]. [toolGroupToeApplication] )'
GO
CREATE UNIQUE CLUSTERED INDEX IDX_view_ToolGroup
ON view_ToolGroup(ToolGroupId, ToolId, TGPurposeId, TGRoleId)
GO
Can anybody suggest an alternative solution to replace UNION and subqueries?
As per all the suggestion above, there is no direct way of doing this. However we can cheat. You could do the following
Break up the statements into two views
Add index to each view
Replace IN with INNER JOIN
User NOT IN while calling the views
As Damien suggested, it would be foolish of me to try and suggest or attempt to judge the logic at this time since we have no idea what the tables represent. I have however restructured the code as per the above which you could use as a template to structure your actual query.
Hope this helps
--Drop Index If Already Aresent
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vw_ToolGroup_One]'))
DROP VIEW dbo.vw_ToolGroup_One
GO
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vw_ToolGroup_Two]'))
DROP VIEW dbo.vw_ToolGroup_Two
GO
--Drop Dependant Tables
IF OBJECT_ID(N'toolGroup_tmp')>0
BEGIN
DROP TABLE toolGroup_tmp
END
CREATE TABLE toolGroup_tmp (ToolGroupId INT,ToolGroupName VARCHAR(100))
INSERT INTO toolGroup_tmp
SELECT 1,'ONE'
GO
IF OBJECT_ID(N'purposeToTG_tmp')>0
BEGIN
DROP TABLE purposeToTG_tmp
END
CREATE TABLE purposeToTG_tmp (ToolGroupId INT,PurposeId int)
INSERT INTO purposeToTG_tmp
SELECT 1,1
GO
IF OBJECT_ID(N'toolGroupToTool_tmp')>0
BEGIN
DROP TABLE toolGroupToTool_tmp
END
CREATE TABLE toolGroupToTool_tmp (ToolGroupId INT,ToolId INT)
INSERT INTO toolGroupToTool_tmp
SELECT 1,1
GO
IF OBJECT_ID(N'toolGroupToeApp_tmp')>0
BEGIN
DROP TABLE toolGroupToeApp_tmp
END
CREATE TABLE toolGroupToeApp_tmp (ToolGroupId INT,AppId INT,toolGroupToeApplicationID INT)
INSERT INTO toolGroupToeApp_tmp
SELECT 1,1,1
GO
IF OBJECT_ID(N'toolGroupToeAppToeRole_tmp')>0
BEGIN
DROP TABLE toolGroupToeAppToeRole_tmp
END
CREATE TABLE toolGroupToeAppToeRole_tmp (ToolGroupId INT,RoleId INT,toolGroupToeApplicationID INT)
INSERT INTO toolGroupToeAppToeRole_tmp
SELECT 1,1,1
GO
IF OBJECT_ID(N'ToolgroupToeApplication_tmp')>0
BEGIN
DROP TABLE ToolgroupToeApplication_tmp
END
CREATE TABLE ToolgroupToeApplication_tmp (ToolGroupId INT,ToolgroupToeApplicationID INT)
INSERT INTO ToolgroupToeApplication_tmp
SELECT 1,1
GO
IF OBJECT_ID(N'PurposeToToolGroup_tmp')>0
BEGIN
DROP TABLE PurposeToToolGroup_tmp
END
CREATE TABLE PurposeToToolGroup_tmp (ToolGroupId INT)
INSERT INTO PurposeToToolGroup_tmp
SELECT 1
GO
IF OBJECT_ID(N'eRole_tmp')>0
BEGIN
DROP TABLE eRole_tmp
END
CREATE TABLE eRole_tmp (RoleId INT)
INSERT INTO eRole_tmp
SELECT 1
GO
--Create Views
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = '
CREATE VIEW dbo.vw_ToolGroup_One WITH SCHEMABINDING
AS
SELECT
tg.ToolGroupId,
tg.ToolGroupName,
tgtt.ToolId,
tga.AppId AS TGAppId,
pttg.PurposeId AS TGPurposeId,
tgr.RoleId AS TGRoleId
FROM dbo.toolGroup_tmp tg
INNER JOIN dbo.purposeToTG_tmp pttg
ON tg.ToolGroupId = pttg.ToolGroupId
INNER JOIN dbo.toolGroupToTool_tmp tgtt
ON tg.ToolGroupId = tgtt.ToolGroupId
INNER JOIN dbo.toolGroupToeApp_tmp tga
ON tg.ToolGroupId = tga.ToolGroupId
INNER JOIN dbo.toolGroupToeAppToeRole_tmp tgar
ON tga.toolGroupToeApplicationID = tgar.toolGroupToeApplicationID
INNER JOIN dbo.ToolgroupToeApplication_tmp tgta
ON tgta.ToolgroupToeApplicationID = tgar.ToolgroupToeApplicationID
INNER JOIN dbo.eRole_tmp tgr
ON tgar.RoleId = tgr.RoleId
'
EXEC SP_EXECUTESQL #SQL
SET #SQL = '
CREATE VIEW dbo.vw_ToolGroup_Two WITH SCHEMABINDING
AS
SELECT tg.ToolGroupId,
tg.ToolGroupName,
NULL AS ToolId,
NULL AS TGAppId,
NULL AS TGPurposeId,
NULL AS TGRoleId
FROM dbo.toolGroup_tmp tg
INNER JOIN dbo.ToolgroupToeApplication_tmp tgtea
ON tg.ToolGroupId = tgtea.ToolGroupId
'
EXEC SP_EXECUTESQL #SQL
-- Create Indexes
CREATE UNIQUE CLUSTERED INDEX IDX_view_ToolGroup_One
ON vw_ToolGroup_One(ToolGroupId, ToolGroupName, ToolId, TGPurposeId, TGRoleId);
CREATE UNIQUE CLUSTERED INDEX IDX_view_ToolGroup_Two
ON vw_ToolGroup_Two(ToolGroupId, ToolGroupName);
GO
-- Invoke Query
SELECT * FROM vw_ToolGroup_One
UNION ALL
SELECT * FROM vw_ToolGroup_Two tgt
WHERE NOT EXISTS ( SELECT 1
FROM dbo.PurposeToToolGroup_tmp pttg
WHERE pttg.ToolGroupId = tgt.ToolGroupId)
I need to surround the following sql script with an if statment that checks the existence of one table. There's a lot more fields to the statement but the snippet below should be enough to get the idea.
If I surround this whole batch with an if statement it doesn't like that i have GOs between if statments. If i take out the GOs it complains about TMP_FIELD being an invalid column.
What are some ways to do this the right way? All i'm doing is taking a bunch of fields and changing from varchar to datetime. This is part of a setup.exe file so I just need it to run once and not for future upgrades. The way I determine that is if a certain table exists then don't run the script.
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
ALTER TABLE MY_TABLE ADD TMP_FIELD datetime
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
UPDATE MY_TABLE SET TMP_FIELD = modifiedDate
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
ALTER TABLE MY_TABLE DROP COLUMN modifiedDate
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
ALTER TABLE MY_TABLE ADD modifiedDate datetime
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
UPDATE MY_TABLE SET modifiedDate = TMP_FIELD
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
ALTER TABLE MY_TABLE DROP COLUMN TMP_FIELD
GO
You don't really need to do all that gymnastic for changing the type of a column, do you?
create table MY_TABLE (
modifiedDate varchar(20)
)
go
insert MY_TABLE (modifiedDate) values ('2012-10-20 17:50:41')
go
select * from MY_TABLE
go
alter table MY_TABLE alter column modifiedDate datetime
go
select * from MY_TABLE
go
drop table MY_TABLE
go
So, I would write your statement like this:
if exists (select table_name from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'MY_TABLE')
begin
alter table MY_TABLE alter column modifiedDate datetime
end
The GOs mark the end of a batch of TSQL statements. You can't mix DDL (data definition language) statements like ALTER TABLE with DML (data manipulation language) statements like UPDATE TABLE in the same batch.
Each batch is compiled on it's own. So when the ALTER TABLE and UPDATE TABLE statements are in the same batch, SQL Server can't compile the update statement because the column modifiedData hasn't actually been created yet.
If you want to get around 'Invalid column ..' errors, one option is to use dynamic SQL.
e.g. :
create table dbo.t1 (id int primary key, cola varchar(20))
go
insert dbo.t1 values (1, 'one')
insert dbo.t1 values (2, 'two')
go
if not exists(select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 't1' and COLUMN_NAME = 'colb')
BEGIN
-- add new column 'colb', and set its value initially to existing values in 'cola'
ALTER TABLE dbo.t1 ADD colb varchar(20)
DECLARE #v NVARCHAR(500)
SET #v = N'UPDATE dbo.t1 SET colb = cola'
EXEC (#v) -- use dynamic SQL, otherwise will get Invalid column name colb error.
END
GO
Note that dynamic SQL should be considered a last resort. David Brabant's answer seems to be the way to go for your original problem.