The following query works perfectly,
insert into [EGallery].dbo.[CustomerDetails]
Select Distinct B.CountyB as 'Mobile' , Cast(BuildingB as Varchar(100)) as 'Email' ,
A.CardCode , A.CardName as 'First Name' , '' as 'Last Name' ,
'' as Gender , Cast(A.Address as Varchar(1000)) as 'Address' , Convert(Varchar(10), A.U_BirthDay,105) as 'birthday' ,
Convert(Varchar(10), A.U_AnnivDay ,105) as 'Anniversary' ,
Case
When A.CardCode Like '%%'+ C.WhsCode +'%%' Then Convert(Varchar(10) , A.DocDate ,105)
Else Convert(Varchar(10), (Select X.CreateDate From OCRD X Where X.CardCode = A.CardCode) ,105) End as 'JoinDate' ,
C.WhsCode as 'JoinStore','Open' as Status ,(Select GETDATE()) as CreatedDateTime,(Select GETDATE()) as ProcessDateTime, '' as StatusMSg
From OINV A
Inner Join INV12 B On A.DocEntry = B.DocEntry
Inner Join INV1 C On A.DocEntry = C.DocEntry
Where C.LineNum = '0'
--B.CountyB not in(select D.Mobile from [EGallery].dbo.[CustomerDetails] D where D.Mobile=B.CountyB)
--not exists (select Mobile from [EGallery].dbo.[CustomerDetails] D where D.Mobile=B.CountyB)
But before I insert records into the [EGallery].dbo.[CustomerDetails] table, I need to check whether the phone number already exists in the table. If the record already exists, there is no need to insert it again. For that I have added one more condition (which I have commented out in the query) but it reports this error while running the query:
Cannot resolve the collation conflict between "SQL_Latin1_General_CP850_CI_AS" and "Latin1_General_CI_AI" in the equal to operation.
According to here you have to add COLLATE DATABASE_DEFAULT to the queries like this:
Where C.LineNum = '0' AND
B.CountyB not in(select D.Mobile from [EGallery].dbo.[CustomerDetails] D where D.Mobile COLLATE DATABASE_DEFAULT = B.CountyB COLLATE DATABASE_DEFAULT) AND
not exists (select Mobile from [EGallery].dbo.[CustomerDetails] D where D.Mobile COLLATE DATABASE_DEFAULT = B.CountyB COLLATE DATABASE_DEFAULT)
Try to do this before your query:
USE [db name for object INV12]
GO
ALTER TABLE [EGallery].dbo.[CustomerDetails]
ALTER COLUMN Mobile
VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL
ALTER TABLE INV12
ALTER COLUMN CountyB
VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL
UPDATE1:
If you have an index on one of this columns, or on both of them, you need to delete it and create index again after a new collation will be changed.
I recommend you to use a MERGE statement, as it
performs insert, update, or delete operations on a target table based on the results of a join with a source table. For example, you can synchronize two tables by inserting, updating, or deleting rows in one table based on differences found in the other table.
Related
In SQL Server, I query data from two VIEW to get records whose OLDPID are -1,-2:
SELECT
T1.*, T2.LEAF
FROM
(SELECT *
FROM VIEW_OBJECT_TREE_DATA
WHERE OLDPID IN (-1, -2)) T1
LEFT JOIN
VIEW_OBJECT_TREE_DATA_GROUP T2 ON T1.NODEID = T2.NODEPID
WHERE
T1.STATE = 1
But it takes 3-4 seconds to get the result.
How can I modify this SQL query to improve its speed?
VIEW_OBJECT_TREE_DATA has OLDPID, OLDID and NAME columns with 450000 records.VIEW_OBJECT_TREE_DATA_GROUP has NODEPID and LEAF with 65000 records.
Below is some sql of view and function:
VIEW_OBJECT_TREE_DATA:
CREATE VIEW dbo.VIEW_OBJECT_TREE_DATA
AS
SELECT(SELECT[dbo].[FNNC_GET_TREE_GUID](0, OBJECT_ID)) AS NODEID,
(SELECT[dbo].[FNNC_GET_TREE_GUID](0, PARENT_ID)) AS NODEPID, 'MY_OBJECT_TABLE' AS[TABLE],
OBJECT_ID AS OLDID, PARENT_ID AS OLDPID, OBJECT_NAME COLLATE DATABASE_DEFAULT AS NAME,
OBJECT_CODE COLLATE database_default AS CODE, OBJECT_TYPE COLLATE database_default AS TYPE,
OBJECT_STATE as STATE
FROM dbo.MY_OBJECT_TABLE
WHERE OBJECT_STATE <> -1
UNION
SELECT(SELECT[dbo].[FNNC_GET_TREE_GUID](1, INDICATOR_ID)) AS NODEID,
(SELECT[dbo].[FNNC_GET_TREE_GUID](0, OBJECT_ID)) AS NODEPID, 'MY_INDICATOR_TABLE' AS[TABLE],
INDICATOR_ID AS OLDID, OBJECT_ID AS OLDPID, INDICATOR_NAME COLLATE DATABASE_DEFAULT AS NAME,
INDICATOR_CODE COLLATE database_default AS CODE, INDICATOR_TYPE COLLATE database_default AS TYPE,
INDICATOR_STATE AS STATE
FROM dbo.MY_INDICATOR_TABLE
WHERE INDICATOR_STATE <> -1
VIEW_OBJECT_TREE_DATA_GROUP :
CREATE VIEW VIEW_OBJECT_TREE_DATA_GROUP
AS
SELECT NODEPID,COUNT(0) AS LEAF FROM VIEW_OBJECT_TREE_DATA GROUP BY NODEPID
Function:
USE[MY_DATABASE]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION[dbo].[FNNC_GET_TREE_GUID](#TYPE INT, #ID INT)
RETURNS UNIQUEIDENTIFIER
AS
BEGIN
RETURN CAST(CAST(#TYPE AS binary(4))+CAST(#ID AS varbinary(28)) AS UNIQUEIDENTIFIER)
END
You can directly join those two views without having to use a subquery.
select TD.*, DG.LEAF
from VIEW_OBJECT_TREE_DATA as TD
left join VIEW_OBJECT_TREE_DATA_GROUP as DG on DG.NODEPID = TD.NODEID
where TD.OLDPID in (-1, -2) and
TD.STATE = 1
Although without seeing those views and the execution plan there is no way of knowing what slows you down.
in some procedure that i work on, i write this code:
update a
set a.custName = b.custName
from #x as a inner join pl_Customer as b on a.Company_Code = b.Company_Code and a.cust = b.Cust
ans i got this error:
Cannot resolve the collation conflict between "Hebrew_CI_AS" and
"SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
i try so solve it with this:
update a
set a.custName = b.custName
from #x as a inner join pl_Customer as b on a.Company_Code = b.Company_Code and a.cust = b.Cust
collate Latin1_General_CI_AI;
but it is still error.
Temporary tables are created using the server's collation by default. It looks like your server's collation is SQL_Latin1_General_CP1_CI_AS and the database's (actually, the column's) Hebrew_CI_AS or vice versa.
You can overcome this by using collate database_default in the temporary table's column definitions, eg :
create #x (
ID int PRIMARY KEY,
Company_Code nvarchar(20) COLLATE database_default,
Cust nvarchar(20) COLLATE database_default,
...
)
This will create the columns using the current database's collation, not the server's.
In your temp table definition #x,add COLLATE DATABASE_DEFAULT to the String columns, like
custName nvarchar(xx) COLLATE DATABASE_DEFAULT NOT NULL
Good day, I am trying to create a data set in SSRS unfortunately I need to create a temporary table in order to create my report. My code is as follows
create table #Tax_Admin (AWD varchar (255), Name varchar(255))
insert into #Tax_Admin
values ('MDSTM','Agent 1'),
('MDSAK','Agent 2'),
('ITDPM','Agent 3'),
('MASEL','Agent 4'),
('ITDEK','Agent 5'),
('ITDFM','Agent 6');
with #transactions_workingwith
as
(
SELECT distinct
[TRANSACTION_ID]
FROM [mmcenvsqlprd01].[MOMDWL1].[ibrststdatEQ].[MOVEMENT_DATA] A
where
(a.TO_QUEUE like '%FINTAX%'
OR a.TO_QUEUE like '%TAXQ%'
OR a.TO_QUEUE like '%TAXCERT%')
and a.TO_STATUS_DATE >= '2017-06-01')
, User_Movements as
(
Select
a.TRANSACTION_ID
,a.POLICY_NUMBER
,a.USER_ID
,a.BILLING_CYCLE_ID
,a.TRANSACTION_TYPE
,a.FROM_STATUS
,a.TO_STATUS
,a.TO_STATUS_DATE
,a.TO_QUEUE
, ROW_NUMBER() over (Partition by a.TRANSACTION_ID order by a.TO_STATUS_DATE) as User_Movement_Nr
,case when (a.TO_QUEUE like '%FINTAX%'
OR a.TO_QUEUE like '%TAXQ%'
OR a.TO_QUEUE like '%TAXCERT%') then 'Tax Queue' else 'Other Queue' end as Queue_Taype
FROM [mmcenvsqlprd01].[MOMDWL1].[ibrststdatEQ].[MOVEMENT_DATA] A
inner join #transactions_workingwith b on a.TRANSACTION_ID Collate SQL_Latin1_General_CP1_CI_AS = b.TRANSACTION_ID Collate SQL_Latin1_General_CP1_CI_AS
where
a.TO_STATUS_DATE >= '2017-06-01')
Select distinct
a.TRANSACTION_ID
,a.POLICY_NUMBER
,convert(varchar,a.TO_STATUS_DATE,112) + isnull(c.EMPLOYEE_NR,d.EMPLOYEE_NR) as EmployeeKey ---Why do we need this empoyee key?
,a.USER_ID
,isnull(c.EMPLOYEE_NR,d.EMPLOYEE_NR) as Emplyee_Nr
,f.[BusinessArea]
,a.TRANSACTION_TYPE
,a.FROM_STATUS
,a.TO_STATUS
,b.TO_STATUS as Next_Status
,b.USER_ID as Next_Status_User
,isnull(e.Name,'Other') as Tax_Admin_Name
,case when b.TO_STATUS like '%FAIL%' THEN 1 ELSE 0 END AS Is_Fail
,case when b.TO_STATUS like '%INFO%' THEN 1 ELSE 0 END AS Is_Info
,case when b.TO_STATUS like '%TRAIN%' THEN 1 ELSE 0 END AS Is_Train
,
case when b.TO_STATUS like '%FAIL%' THEN 1 ELSE 0 END
+ case when b.TO_STATUS like '%INFO%' THEN 1 ELSE 0 END
+ case when b.TO_STATUS like '%TRAIN%' THEN 1 ELSE 0 END as Returned
,a.TO_STATUS_DATE
,a.TO_QUEUE
,a.User_Movement_Nr
,a.BILLING_CYCLE_ID
,1 as Movement
from User_Movements a
inner join User_Movements b
on a.TRANSACTION_ID = b.TRANSACTION_ID and a.User_Movement_Nr + 1 = b.User_Movement_Nr
left JOIN [mmcenvsqlprd01].momdwl1.ibrststcnfEQ.IBRS_USER_INFO c
on a.USER_ID Collate SQL_Latin1_General_CP1_CI_AS = c.USER_ID Collate SQL_Latin1_General_CP1_CI_AS
left JOIN [mmcenvsqlprd01].momdwl1.ibrststcnfWealth.IBRS_USER_INFO d
on a.USER_ID Collate SQL_Latin1_General_CP1_CI_AS = d.USER_ID Collate SQL_Latin1_General_CP1_CI_AS
left join #Tax_Admin e on b.USER_ID Collate SQL_Latin1_General_CP1_CI_AS = e.AWD Collate SQL_Latin1_General_CP1_CI_AS
inner join [mmcenvsqlbi01].[Master_Data].[Trans].[Employee_Snapshot] f
on convert(varchar,a.TO_STATUS_DATE,112) + isnull(c.EMPLOYEE_NR,d.EMPLOYEE_NR) Collate SQL_Latin1_General_CP1_CI_AS = f.[EmployeeKey] Collate SQL_Latin1_General_CP1_CI_AS
where a.Queue_Taype = 'Tax Queue'
drop table #Tax_Admin
How would I go about Moving this code over to SSRS?
I have tried the With Clause and that is not working. I have tried building a Null table and then updating the information, which didn't work.
can someone please help me?
What's the problem with creating a temporary table in SSRS? I ran a quick test to make sure you can do this in SSRS 2012, and it appears that this runs fine, e.g. my dataset is defined as:
CREATE TABLE #temp(id INT, name VARCHAR(10));
INSERT INTO #temp SELECT 1, 'Harry';
INSERT INTO #temp SELECT 2, 'Megan';
SELECT * FROM #temp;
What's the actual error that you are getting when you try to do this in SSRS?
If you can't get this to work then you could create a stored procedure (no parameters) and simply paste your script into that, then use the Query Type = Stored Procedure and pick the one you just created in SSRS.
The most common problem with using WITH is when your previous statement hasn't been terminated with a ; correctly, but in your script this doesn't seem to be the case? People often right ;WITH to workaround this issue.
You could try using a table variable, i.e. change #Tax_Admin to #Tax_Admin and DECLARE it as a TABLE.
I'm building a package in SSIS that first acquires source data from from another server and loads into my server. From there I have another package that manipulates this source data and loads a new table.
I want to prevent this 'manipulation' package from running if something failed on my 'source' package. I can talk it out but not Syntax it out...
If MyTABLE exists and count(*) from MyTABLE > 0 then 'GOOD' else 'BAD' I was going to have a constraint that wouldn't run the rest of the package if anything came back bad. If this is an asinine way of achieving this then please show me the easier way to achieve this.
The ultimate goal would be to have a list of 'GOOD' or 'BAD' and the table name as the next column so if anything fails I can get an email of my query that would quickly show me what is bad and what is good.
Source_Check Source_Table
GOOD TABLE1
BAD TABLE2
GOOD TABLE3
etc.....
my issue is I get an error trying to count(*) from a table that doesn't exist... Not sure how to overcome this :(
There are probably easier ways to go about this, I'm just a newb is all. Could phrase my search right to get any results from google.
Metadata is going to be your friend. Assuming SQL Server, you can write a simple query like
SELECT
*
FROM
sys.schemas AS S
INNER JOIN sys.tables AS T
ON T.schema_id = S.schema_id
WHERE
S.name = N'dbo'
AND T.name = N'SomeTable';
If that returns a result, then you know your table exists.
The problem with SELECT COUNT(*) is that the table must exist. It also locks forces you to crawl the table. There are tricks for addressing this but my favorite is to go back to the metadata well. Look at this query. It's going to generate a list of all the tables and their row counts in no time at all.
SELECT
s.[Name] as [Schema]
, t.[name] as [Table]
, SUM(p.rows) as [RowCount]
FROM
sys.schemas s
LEFT OUTER JOIN
sys.tables t
ON s.schema_id = t.schema_id
LEFT OUTER JOIN
sys.partitions p
ON t.object_id = p.object_id
LEFT OUTER JOIN
sys.allocation_units a
ON p.partition_id = a.container_id
WHERE
p.index_id in(0,1) -- 0 heap table , 1 table with clustered index
AND p.rows is not null
AND a.type = 1 -- row-data only , not LOB
GROUP BY
s.[Name]
, t.[name]
ORDER BY
1
, 2
Now you can compare that resultset to your list of tables that may or may not exist.
You could try something like this:
DECLARE #SourceTables TABLE (tbl_name VARCHAR(100))
INSERT INTO #SourceTables VALUES('TABLE1'),('TABLE2'),('TABLE3');
WITH CTE
AS
(
SELECT o.name AS tbl_name,
i.[Rows] AS row_count
FROM sysindexes i
INNER JOIN sysobjects o
ON i.id = o.id
WHERE i.IndId < 2
AND xtype = 'U'
)
--Returns tables that don't exist
SELECT CASE
WHEN B.tbl_name IS NULL AND B.row_count > 0 --when there is no table and row count is greater than 0, then good
THEN 'Good'
ELSE 'Bad'
END AS Source_Check,
A.tbl_name
FROM #SourceTables A
LEFT JOIN CTE B
ON A.tbl_name = B.tbl_name
Theoretical Results:
Source_Check tbl_name
------------ -------------------------
Good TABLE1
Good TABLE2
Bad TABLE3
I assume you're using SQL Server based on the SSIS package. You could simplify things using OBJECT_ID Try Something Like the following....
CREATE TABLE #OUTPUT(Source_Check VARCHAR(10), Source_Table VARCHAR(10))
IF OBJECT_ID('DBNAME.dbo.Table1') IS NOT NULL
BEGIN
INSERT INTO #OUTPUT VALUES ('GOOD', 'TABLE1')
END
ELSE
INSERT INTO #OUTPUT VALUES ('BAD', 'TABLE1')
END
IF OBJECT_ID('DBNAME.dbo.Table2') IS NOT NULL
BEGIN
INSERT INTO #OUTPUT VALUES ('GOOD', 'TABLE2')
END
ELSE
INSERT INTO #OUTPUT VALUES ('BAD', 'TABLE2')
END
IF OBJECT_ID('DBNAME.dbo.Table3') IS NOT NULL
BEGIN
INSERT INTO #OUTPUT VALUES ('GOOD', 'TABLE3')
END
ELSE
INSERT INTO #OUTPUT VALUES ('BAD', 'TABLE3')
END
SELECT * FROM #OUTPUT
We have a legacy application which created multiple tables with the following naming convention: table_20140618, table_20140623, etc where the date is when the program run. I am trying to clean up the database now, and drop some of these tables.
In each table there are two fields: DateStarted and DateFinished. I want to select the tables (and then drop them) where DateStarted has value and DateFinished is NOT null.
At the moment I am using the following query to select all the tables that start with 'table_'
such as:
Select (TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME LIKE 'table_%';
I am not sure how to get all the tables together by searching within their fields. I could do it through the code, but that should mean multiple hits on the database. Any ideas?
Made this after my first comment above, but you should be able to alter the code to fit your specs. Basically, this will use dynamic SQL to generate the commands based on your filters and conditions. So you can use whatever conditions you want in the SELECT #SQL = ... part, to check for the dates, and then add the table name when the conditions are met.
The script returns a list with tablenames and the drop command, so you can check what you're doing before you do it. But from there you can just copy the drop command list and execute it if you want.
IF OBJECT_ID('tempdb..#TABLES') IS NOT NULL
DROP TABLE #TABLES
CREATE TABLE #TABLES (ROWNMBER INT IDENTITY(1,1), TABLENAME VARCHAR(256) COLLATE DATABASE_DEFAULT)
/*
-- Old code to fetch ALL tables with specified name
INSERT INTO #TABLES
SELECT name
FROM sys.tables
WHERE name LIKE 'table[_]%'
*/
-- Updated code to fetch only those tables which contain the DateStarted and DateFinished columns
INSERT INTO #TABLES
SELECT TAB.name
FROM sys.tables TAB
LEFT JOIN sys.columns C1 on C1.object_id = TAB.object_id
AND C1.name = 'DateStarted'
LEFT JOIN sys.columns C2 on C2.object_id = TAB.object_id
AND C2.name = 'DateFinished'
WHERE TAB.name LIKE 'table[_]%'
AND C1.name IS NOT NULL AND C2.name IS NOT NULL
IF OBJECT_ID('tempdb..#DROPPABLE_TABLES') IS NOT NULL
DROP TABLE #DROPPABLE_TABLES
CREATE TABLE #DROPPABLE_TABLES (TABLENAME VARCHAR(256) COLLATE DATABASE_DEFAULT)
DECLARE #ROW_NOW INT, #ROW_MAX INT, #SQL VARCHAR(MAX), #TABLENAME VARCHAR(256)
SELECT #ROW_NOW = MIN(ROWNMBER), #ROW_MAX = MAX(ROWNMBER) FROM #TABLES
WHILE #ROW_NOW <= #ROW_MAX
BEGIN
SELECT #TABLENAME = TABLENAME FROM #TABLES WHERE ROWNMBER = #ROW_NOW
SELECT #SQL =
'IF (SELECT COUNT(*) FROM '+#TABLENAME+' WHERE DateStarted IS NOT NULL) > 0
AND (SELECT COUNT(*) FROM '+#TABLENAME+' WHERE DateFinished IS NOT NULL) > 0
SELECT '''+#TABLENAME+''''
INSERT INTO #DROPPABLE_TABLES
EXEC(#SQL)
SET #ROW_NOW = #ROW_NOW+1
END
SELECT *, 'DROP TABLE '+TABLENAME DROPCOMMAND FROM #DROPPABLE_TABLES
EDIT:
As per your comment, it seems not all such tables have those columns. You can use the following script to identify said tables and which column is missing, so you can check into them further. And you can use the same idea to filter the results of the first query to only count in tables which have those columns.
SELECT TAB.name TABLENAME
, CASE WHEN C1.name IS NULL THEN 'Missing' ELSE '' END DateStarted_COL
, CASE WHEN C2.name IS NULL THEN 'Missing' ELSE '' END DateFinished_COL
FROM sys.tables TAB
LEFT JOIN sys.columns C1 on C1.object_id = TAB.object_id
AND C1.name = 'DateStarted'
LEFT JOIN sys.columns C2 on C2.object_id = TAB.object_id
AND C2.name = 'DateFinished'
WHERE TAB.name LIKE 'table[_]%'
AND (C1.name IS NULL
OR C2.name IS NULL)