Excel Invalid Object Name when using a temp table and a parameter - sql

When I create a connection to SQL in Excel that has a temp table for a lookup and I hard code the parameters for the SQL query, everything runs fine. When I change the hard coded parameters to ? to be able to use dynamic parameters from a cell, I get an Invalid Object Name error on the Temp Table. ANy help is greatly appreciated.
SET NOCOUNT ON
CREATE TABLE #ACTUALPENDCODESLIST
(ID INT IDENTITY(1,1) PRIMARY KEY,
PENDCODE CHAR(2),
PENDDESCRIPTION VARCHAR(255),
AREAOFOWNERSHIP VARCHAR(255),
PendQueue VARCHAR(255),
PendPriority INT)
INSERT INTO #ACTUALPENDCODESLIST VALUES ('02','PEND - PHYSICIAN/GROUP NOT CONTRACTED FOR RENAL CARE SERVICES','N/A','Not Applicable',999)
INSERT INTO #ACTUALPENDCODESLIST VALUES ('03','PEND - PROC DETAIL NOT FOUND ON FILE','Claims','MCLAIM/HCLAIM',267)
SELECT DISTINCT(SUBSTRING(ph.FREE_FORM_DATA, 16,2)) AS 'Pend Code',
apc.PENDDESCRIPTION AS 'Description',
COUNT(DISTINCT(ph.CLAIM_NBR)) AS 'Count'
FROM process_hist ph
INNER JOIN #ACTUALPENDCODESLIST apc
ON SUBSTRING(ph.FREE_FORM_DATA, 16,2) = apc.PENDCODE
WHERE ph.YMDTRANS BETWEEN ? AND ?
AND ph.OP_NBR NOT LIKE 'SYS%'
AND ph.OP_NBR NOT LIKE 'SMK%'
AND SUBSTRING(ph.FREE_FORM_DATA, 13,2) = 'EX'
AND SUBSTRING(ph.FREE_FORM_DATA, 16,2) IN (SELECT PENDCODE FROM #ACTUALPENDCODESLIST)
GROUP BY SUBSTRING(ph.FREE_FORM_DATA, 16,2), apc.PENDDESCRIPTION
ORDER BY [Count] DESC, [Pend Code]
DROP TABLE #ACTUALPENDCODESLIST```

Related

Why is this temporary table throwing an error about the number of column supplied?

I'm trying to run this specific code for a temp table, but somehow I get this error
Column name or number of supplied values does not match table definition
What's wrong?
DROP TABLE IF EXISTS #GamesDistribution
CREATE TABLE #GamesDistribution
(
Platform nvarchar(255),
Name nvarchar(255),
NA_Sales numeric,
EU_Sales numeric,
JP_Sales numeric
)
INSERT INTO #GamesDistribution
SELECT
properties.Platform,
properties.Name,
revenue.NA_Sales,
revenue.EU_Sales,
revenue.JP_Sales
FROM
games_properties AS Properties
JOIN
games_revenue AS Revenue ON properties.Game_ID = Revenue.Game_ID
--GROUP BY properties.platform
--ORDER BY Total_Games DESC, Total_NA_Sales DESC, Total_EU_Sales DESC, Total_JP_Sales DESC;
The problem here is that prior to you running your batch the table already exists. As such when the batch is parsed, by the compiler, the compilation fails; because the number of columns doesn't match that of the table already exists.
This can be replicated with the following:
CREATE TABLE #t (I int);
INSERT INTO #t (I)
VALUES(1);
GO
DROP TABLE IF EXISTS #t;
CREATE TABLE #t (I int, D date);
INSERT INTO #t
VALUES(2,GETDATE());
GO
SELECT *
FROM #t;
GO
DROP TABLE #t
db<>fiddle
This returns the error:
Msg 213, Level 16, State 1, Line 10
Column name or number of supplied values does not match table definition.
And the dataset:
I
1
This is because the 2nd batch, with the DROP TABLE IF EXISTS never ran; the compilation failed.
The "simple" solution here would be to put your DROP IF EXISTS in a separate batch, and also specify your columns:
DROP TABLE IF EXISTS #GamesDistribution;
GO
CREATE TABLE #GamesDistribution (Platform nvarchar(255),
Name nvarchar(255),
NA_Sales numeric, --Where is your precision and scale?
EU_Sales numeric, --Where is your precision and scale?
JP_Sales numeric); --Where is your precision and scale?
INSERT INTO #GamesDistribution (Platform,Name, NA_Sales,EU_Sales,JP_Sales)
SELECT properties.Platform,
properties.Name,
revenue.NA_Sales,
revenue.EU_Sales,
revenue.JP_Sales
FROM dbo.games_properties AS Properties
JOIN dbo.games_revenue AS Revenue ON properties.Game_ID = Revenue.Game_ID;
You can actually do this way
DROP TABLE IF EXISTS #GamesDistribution
SELECT properties.Platform,
properties.Name,
revenue.NA_Sales,
revenue.EU_Sales,
revenue.JP_Sales
INTO #GamesDistribution
FROM games_properties AS Properties
JOIN games_revenue AS Revenue
ON properties.Game_ID = Revenue.Game_ID
and then you can check the columns' data types of the temp table:
EXEC tempdb..sp_help '#GamesDistribution'
SELECT *
FROM tempdb.sys.columns
WHERE [object_id] = OBJECT_ID('tempdb..#GamesDistribution');
Note: It's always better to ensure the columns' data types. Your query might list different columns' data types.
Add GO statement under drop table as below.
DROP TABLE IF EXISTS #GamesDistribution
GO
CREATE TABLE #GamesDistribution
(
.
.
.

Why a SQL Server join is taking too long to execute?

I am populating a temporary table with data, below is the definition of my temp table.
DECLARE #PurgeFilesList TABLE
(
JobFileID BIGINT,
ClientID INT,
StatusID INT,
IsPurgeSuccessfully BIT,
ReceivedDate DATETIME,
FilePath VARCHAR(2000),
StatementPath VARCHAR(2000)
)
Insert logic to populate temp table, after this I am making an additional join with a table named Account:
SELECT
JobFileID,
PFL.ClientID,
StatusID,
IsPurgeSuccessfully,
ReceivedDate,
CASE
WHEN FilePath IS NULL THEN StatementPath
ELSE FilePath
END 'FilePath'
FROM
#PurgeFilesList PFL
INNER JOIN
Account(NOLOCK) A ON ISNULL(PFL.ClientID, 0) = ISNULL(A.ClientID, 0)
AND A.HoldStatementPurge = 0
But, this join is taking too much time. Although total number of rows in Account table is less than 5000.
Account table schema:
Column_name Type Computed Length
-----------------------------------------------
AccountID bigint no 8
AccountNumber varchar no 32
PrimaryCustomerName varchar no 100
LastName varchar no 100
ClientName varchar no 32
BankID varchar no 32
UpdatedDate datetime no 8
IsPurged bit no 1
PurgeDate datetime no 8
ClientID int no 4
HoldStatementPurge bit no 1
Kindly let me know, if any other info is required.
Execution Plan:
Since you are not using any column from Account so, i would use EXISTS :
select fl.JobFileID, fl.ClientID, fl.StatusID,
fl.IsPurgeSuccessfully, fl.ReceivedDate,
isnull(FilePath, StatementPath) as FilePath
from #PurgeFilesList fl
where fl.ClientID is null or
exists (select 1
from Account a
where a.clientid = fl.clientid and a.HoldStatementPurge = 0
);
For the performance, index would be helpful on Account(clientid,HoldStatementPurge) & same as table variable. Just make sure your table variable has some smaller amount of data if that is not the case then you will need to use temporary tables & provide appropriate index on that table.
Your Account schema is missing nullable yes/no information. Having said that I assume Account.ClientID is not nullable so ISNULL(PFL.ClientID, 0) = A.ClientID would do too. Anyway.
My guess is you are missing a couple of well placed indexes here such as:
CREATE INDEX IX_Account_ClientID_HoldStatementPurge ON Account(ClientID, HoldStatementPurge)
Or just
CREATE INDEX IX_Account_ClientID ON Account(ClientID)
I'd say try creating both while checking the query plan first.
Also, you might want to use a Temporary Table (CREATE TABLE #TempTable ...) for this scenario instead of a Table Variable (DECLARE #TempTable TABLE ...) so you can apply an additional index to speed up things:
CREATE TABLE #PurgeFilesList
(
JobFileID BIGINT PRIMARY KEY,
ClientID INT,
StatusID INT,
IsPurgeSuccessfully BIT,
ReceivedDate DATETIME,
FilePath VARCHAR(2000),
StatementPath VARCHAR(2000)
)
CREATE INDEX #IX_PurgeFilesList_ClientID ON #PurgeFilesList(ClientID)
The reason for this is that it is not possible to create non-clustered indexes on Table Variables (only a primary key is permitted).
Please check the record size in table #PurgeFilesList.
try to use Temp Table instead of Table Variable.

how to loop multipe variables in to one destination table using SSIS

I have three variables
#Emp = 'Select EmpName from Employee',
#Department = 'Select DeptName from Department',
#Customer = 'Select Custname from Customer'
and I have destination table
Output :
ID tbl_statement
1 Select EmpName from Employee
2 Select DeptName from Department
3 Select Custname from Customer
How can I loop these three variables into destination table using SSIS
I would propose you use an Execute SQL Task to store this data.
Given a target table such as the following
CREATE TABLE dbo.SO_53235748
(
ID int identity(1,1) NOT NULL
, tbl_statement nvarchar(max) NOT NULL
, AsOfDate datetime NOT NULL CONSTRAINT DF_dbo_SO_53235748 DEFAULT (GETDATE())
);
We'll use an OLE DB Connection and parameterize a query like this
INSERT INTO dbo.SO_53235748(tbl_statement)
SELECT D.tbl_statement
FROM
(
VALUES(?), (?), (?)
) D(tbl_statement);
The ? is a placeholder in the OLE DB Connection manager syntax. In the preceding query, it expects 3 parameters. In the event you have more or fewer parameters, then you would need to add/remove elements in the fifth line.
In the parameters tab, we will map based on ordinal positions, zero based, our variables into the parameters
Please try using For Each Variable looping in For Each Loop Task in SSis
Thanks

While inserting data to two tables using stored procedure I am getting a mismatch error

I have a table called CompanyMaster_tbl with a table structure as follows.
Cid CompanyName Deleted
and another table named DepartmentMaster_tbl,with a table structure as follows.
dtld dtname dtphone dtemail cid deleted
I've written a stored procedure for inserting data into these tables as follows.
CREATE PROCEDURE [dbo].[InsertDetails](
#companyName varchar(150),
#dname varchar(150),
#dphon varchar(150),
#deleted int,
#cid int OUTPUT
) AS
BEGIN
INSERT INTO [dbo].CompanyMaster_tbl
VALUES (#companyName)
select #cid=cid
from [dbo].CompanyMaster_tbl
WHERE ##ROWCOUNT > 0 AND cid = scope_identity()
insert into DepartmentMaster_tbl
values(#dname,
#dphon)
end
When I execute this SP, i am getting error like this:
Column name or number of supplied values does not match table definition.
try this , mention coloumn name
INSERT INTO [dbo].CompanyMaster_tbl (CompanyName )
VALUES (#companyName)
INSERT into DepartmentMaster_tbl (dname,dphon)
values(#dname, #dphon)
You are giving wrong number of values to the table i.e. you have two columns in table CompanyMaster_tbl(i think your cid is identity(auto generated) there fore i did not mention it) but you can give only one value to the table, and same thing applies for DepartmentMaster_tbl. if you can't give the values to the table then mention column names in the insert statement otherwise give all column value
e.g.
Insert into CompanyMaster_tbl(CompanyName) values(#companyName)
or
Insert into CompanyMaster_tbl values(#companyName, #deleted)

Solutions for tracking how many times certain parameters are used in a stored procedure SQL Server 2008

In my database have tables with structures similar to:
create table ItemNameSearches
(ItemName varchar(50) not null,timesSearched int not null,
primary key(ItemName))
and
create table ItemList
(ItemName varchar(50),
primary key (ItemName))
My idea is to have people enter in through a webform a comma-separated list of values so that they can get information about certain items. The table ItemList contains information about the item for which they searched (although the table structure doesn't reflect that in this example). If, however, the item searched for doesn't appear in the ItemList table, I would like for that ItemName to be inserted into the ItemNameSearches so I could have a better idea of what people are searching for.
Scenario 1: an item is searched for the first time and a new row is inserted into the ItemNameSearches table. I'm pretty sure this is an area for triggers, but I'm not familiar with using them so I wrote the following stored procedure:
create proc spSearchItemName
#itemName1 varchar(50)
,#itemName2 varchar(50) = null
,#itemName3 varchar(50) = null
,#itemName4 varchar(50) = null
as
begin
;with searchList
as
(select x.itemName
from (values (#itemName1)
,(#itemName2)
,(#itemName3)
,(#itemName4)
) as x(itemName)
where x.itemName is not null
--these are optional parameters just to give the user more flexibility
--on if they want to look at multiple items at once or not
)
insert into ItemNameSearches(itemName,timesSearched)
values
(
(select sl.itemName
from searchList as sl
left outer join ItemList as il
on il.itemName=sl.itemName
where il.itemName is null
--this subquery finds the items searched for that are not present in the
--itemlist table and sets timesSearched =1 for each
),1
)
end
This is well and good for the items that are searched for that do not appear in the ItemList table, but I would have to do something like the following procedure if they DID search for an item that was in the ItemList table
;with searchList
as
(select x.itemName
from (values ('item 1')
,('item 2')
,('item 3')
,('item 5')
) as x(itemName)
)
update ins
set timesSearched = timesSearched +1
from ItemNameSearches as ins
where itemName in
(select itemName from searchList)
So this will add 1 to the number of times an item was searched for if it exists in the ItemList table. Can someone provide a neat manner of how to solve these two different situations? Is this something that is a good candidate for triggers?
Thanks to #Gordon Linoff for providing the direction of using the merge statement, it ended up working perfectly for what I wanted to do. I ended up using the following sproc and it works fine.
alter proc spSearchDrugName
#drugName1 varchar(50)
,#drugName2 varchar(50) = null
,#drugName3 varchar(50) = null
,#drugName4 varchar(50) = null
,#drugName5 varchar(50) = null
as
begin
declare #searchList table(drugName varchar(50))
insert into #searchList
values (#drugName1)
,(#drugName2)
,(#drugName3)
,(#drugName4)
,(#drugName5)
merge DrugListSearches as d
using(select drugName from #searchList where drugName is not null) as s
on s.drugName = d.drugName
when matched then
update set d.timesSearched = d.timesSearched + 1
when not matched then
insert (drugname,timesSearched) values (s.drugName,1);
end