I am trying to use a internal SQL command to query a table and use the result to query another but am getting the following problem
"Msg 137, Level 16, State 1, Line 10
Must declare the scalar variable "#ListofPropIDs"."
Any help would be appreciated
DECLARE #ListofPropIDs TABLE(IDs VARCHAR(100));
INSERT INTO #ListofPropIDs
SELECT Id
FROM Property
WHERE CreatedBy = 'oliver#test.co.uk'
SELECT
COUNT (Digits)
FROM dbo.CallInfo
WHERE Digits = #ListofPropIDs;
GO
DECLARE #ListofPropIDs TABLE(IDs VARCHAR(100));
INSERT INTO #ListofPropIDs
SELECT Id
FROM Property
WHERE CreatedBy = 'oliver#test.co.uk'
SELECT
COUNT (Digits)
FROM dbo.CallInfo C
INNER JOIN #ListofPropIDs s
on s.IDs = c.Digits
without knowing what you want to achieve, something like this should work but may not be correct:
DECLARE #ListofPropIDs TABLE(IDs VARCHAR(100));
INSERT INTO #ListofPropIDs
SELECT Id
FROM Property
WHERE CreatedBy = 'oliver#test.co.uk'
SELECT
COUNT (Digits)
FROM dbo.CallInfo
WHERE Digits in (SELECT IDs FROM #ListofPropIDs)
Your original query is trying to use a table variable as part of a where clause as if it where a column which is not correct.
#ListofPropIDs is a table and you're using it like a Value.
use :
SELECT
COUNT (Digits)
FROM dbo.CallInfo
WHERE Digits IN ( SELECT IDs from #ListofPropIDs)
GO
You can't use a table as where condition value
Instead you can use SQL: IN Condition
SELECT COUNT (Digits)
FROM dbo.CallInfo
WHERE Digits IN (Select Id From #ListofPropIDs)
Or use Inner Join
SELECT COUNT (Digits)
FROM dbo.CallInfo C
Inner Join #ListofPropIDs T On T.Id=C.Digits
Related
I am using the table type as my input parameter in my stored procedure and I am passing in a list of comma separated Catalog Ids from my C# application.
But there is also an option on the web page where users can select 'All Catalog Ids' on the multi-select Catalog drop down.
What is the best 'short hand' way to write the query? Like, If I have a varchar variable as my input variable, then I would have written
SELECT [FIELD1], [FIELD2] FROM CATALOG WHERE (**#VarcharVariable is NULL** or CatalogName = #VarcharVariable ) for example.
But I am struggling to get that kind of 'short hand' notation on the WHERE clause, with this table type input parameter, as Table type parameter cannot be NULL.
I don't want to write a bunch of IF clauses, as I have 4 input parameters of list type that I am sending to this proc and Catalog ID is just one of them. I just want to JOIN the values in these input parameters with my base tables and send the output with a concise single query. Unfortunately any of these 4 table type input parameters can have 'All' as its value. If ALL, I just have to get everything of that entity.
I want to join these input parameters with my base tables ONLY if they have valid ids in the table and does not have 'All' equivalent.
Thanks
I used a bit variable. Here IDList is a user-defined type that I have created. If we see the WHERE condition below, I used the OR condition to keep it to one concise query but yet join bunch of base tables based on these list type (comma delimited string of IDs) of input parameters.
When I have to pass ALL from my c# app, I literally null the datatable input parameter out, so that these bit variables will have a value of 0 and the query pulls in all records for that entity..
CREATE PROC dbo.MyProc
(
#CatelogIDs IDList READONLY,
#TaskIDs IDList READONLY,
#SomeOtherIDs IDList READONLY
)
AS
BEGIN
DECLARE #bCatIDs bit=0
DECLARE #bTaskIDs bit=0
DECLARE #bSomeOtherIDs bit=0
IF EXISTS (SELECT 1 FROM #CatelogIDs)
BEGIN
SET #bCatIDs =1
END
IF EXISTS (SELECT 1 FROM #TaskIDs)
BEGIN
SET #bTaskIDs =1
END
IF EXISTS (SELECT 1 FROM #SomeOtherIDs)
BEGIN
SET #bSomeOtherIDs =1
END
SELECT col1, col2,col3
FROM [dbo].[MainTable] r
JOIN [dbo].Catalogs c ON c.ID = r.CatalogID
JOIN [dbo].[Tasks] t ON t.ID = r.TaskId
JOIN [dbo].[SomeotherTable] s ON s.ID = r.SomeotherID
WHERE (#bCatIDs = 0 OR r.CatalogID in (SELECT IDs FROM #CatelogIDs))AND
(#bTaskIDs = 0 OR r.TaskID in (SELECT IDs FROM #TaskIDs)) AND
(#bSomeOtherIDs = 0 OR r.SomeotherID in (SELECT IDs FROM #bSomeOtherIDs))
I have three Tables :
tbl_Publisher [Publisher_ID, addr,account-num,...,city];
tbl_Title [Title_ID, frequency, publisher,.., Publisher_ID];
tbl_Invoice [Invoice_ID, ordered_Date,...,Title_ID];
I would like to return a list of Titles by Publisher and each Title has the count number of Invoices it contains. in one result set.
I'm using a stored procedure as following :
PROCEDURE [dbo].[usp_GetTitlesbyPublisher]
-- Add the parameters for the stored procedure here
#PublisherID INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
-- Insert statements for procedure here
SELECT Title_ID,TitleName,pub_type,Frequency , Holdings ,tbl_Title.publisher ,section ,tbl_Title.Publisher_ID from tbl_Title, tbl_Publisher
where tbl_Title.Publisher_ID = tbl_Publisher.Publisher_ID
and #PublisherID = tbl_Publisher.Publisher_ID
END
How can I return the number of Invoice by each Title ?
You can probably accomplish this with a GROUP BY:
SELECT t.Title_ID, t.TitleName, p.pub_type,
t.Frequency, Holdings, t.publisher, section,
t.Publisher_ID, count(i.Invoice_ID) as NoOfInvoices
from tbl_Title t
inner join tbl_Publisher p on t.Publisher_ID = p.Publisher_ID
left join tbl_Invoice i on i.Title_ID = t.Title_ID
where #PublisherID = p.Publisher_ID
group by t.Title_ID, t.TitleName, p.pub_type, t.Frequency,
Holdings, t.publisher, section, t.Publisher_ID
Not checked the syntax on this.
SELECT COUNT(tbl_Invoice.Invoice_ID) 'InvoiceCount',Title_ID,TitleName,pub_type,Frequency, Holdings ,tbl_Title.publisher ,section ,tbl_Title.Publisher_ID
FROM tbl_Title
INNER JOIN tbl_Publisher ON tbl_Publisher.Publisher_ID = tbl_Title.Publisher_ID
INNER JOIN tbl_Invoice ON tbl_Invoice.Invoice_ID = tbl_Title.Invoice_ID
WHERE tbl_Publisher.Publisher_ID = #PublisherID
GROUP BY
Title_ID,TitleName,pub_type,Frequency, Holdings ,tbl_Title.publisher ,section ,tbl_Title.Publisher_ID
While binding data to Dataview getting this error but Parameters are correctly sending there values.
Seems DBhelper class is throwing this error but don't know why
My procedure:
insert #leads(opp_lead,opp_NAME,CNT)
select opp_lead,'LEAD'+opp_lead,COUNT(*) from #pipeline GROUP BY opp_lead
UPDATE #leads SET opp_NAME=CONTACT_NAME FROM TBLCONTACT C, #leads L WHERE CONVERT(VARCHAR(50),L.opp_lead)=CONVERT(VARCHAR(50),C.CONTACT_ID)
COUNT(*) DESC
create table #YearlyEndCampaign
(
slno INT ,
lvl int
)
SELECT TOP 1 #MAXLEADS=COUNT(*) FROM #pipeline GROUP BY opp_lead ORDER BY COUNT(*) DESC
INSERT INTO #YearlyEndCampaign(slno,LVL)
SELECT SEQ,0 FROM (SELECT TOP (#MAXLEADS) seq = ROW_NUMBER() OVER (ORDER BY number) FROM [master]..spt_values)S
C# code:
long businessID = Convert.ToInt64(Session["BusinessID"]);
long YEAR = Convert.ToInt64(2015);
long UserID = Convert.ToInt64(Session["Contact_ID"]);
BeggingDA objBeggingDA = new BeggingDA();
DataView dv = (new BeggingDA()).BeggingLoadByBusinessID(YEAR, businessID, UserID);
As you say, the first SELECT TOP 1 #MAXLEADS=COUNT(*) FROM #pipeline statement is not returning any data. This means that #MAXLEADS is null.
If you then run select top (NULL) FROM [master]..spt_values you will get the TOP clause contains an invalid value error, because you are not passing a numeric value to TOP.
The solution is to check if #MAXLEADS is null before doing the insert - if there aren't any rows, you would be selecting top 0, so it is pointless doing the insert anyway. A simple IF #MAXLEADS IS NOT NULL should be sufficient:
SELECT TOP 1 #MAXLEADS=COUNT(*) FROM #pipeline GROUP BY opp_lead ORDER BY COUNT(*) DESC
IF #MAXLEADS IS NOT NULL BEGIN
INSERT INTO #YearlyEndCampaign(slno,LVL)
SELECT SEQ,0 FROM (SELECT TOP (#MAXLEADS) seq = ROW_NUMBER() OVER (ORDER BY number) FROM [master]..spt_values)S
END
Basically i have 3 tables like this (with many to many relationship);
And i am querying searching like this;
ALTER PROC [dbo].[usp_ContactSearch]
(
#PersonName varchar(60)= '',
#MobileNo varchar(20)= '',
#Nationlity varchar(50)='' ,
#ContactTypes varchar(max) = ''
)
AS
BEGIN
SELECT DISTINCT c.ContactId, c.PersonName, ct.ContactType, ct.ContactTypeId
FROM Contact c
LEFT OUTER JOIN ContactWithContactType cct
ON c.ContactId = cct.ContactId
LEFT OUTER JOIN ContactType ct
ON cct.CountactTypeId = ct.ContactTypeId
WHERE
c.PersonName LIKE CASE WHEN #PersonName='' THEN c.PersonName ELSE '%'+#PersonName+'%' END
AND
c.MobileNo1 LIKE CASE WHEN #MobileNo='' THEN c.MobileNo1 ELSE '%'+#MobileNo+'%' END
AND
c.Nationality LIKE CASE WHEN #Nationlity='' THEN c.Nationality ELSE '%'+#Nationlity+'%' END
END
So, the result data by default is;
So, from the Front End, i have ContactTypes (which are dynamic i.e comming from contact types table), and the interface looks like this
Now, whenever user check the PropertyOwner(ContactTypeId=1), The data should be filtered and only those contacts should be shown which are belong to ContactTypeId=1
Silarly, when i check the second checkbox i.e Tenant(ContactTypeId=2). The data should be more filtered and only those contacts will be displayed which belongs to ContactTypeId= 1 and 2. And similarly for 3rd ContactType, the data should be more filtered and so on and so forth.
So, the problem is ContactTypes are dynamic and i don't know how to handle this situation.
Any help regards to the query and performance is much apreciated.
Try this. This will work...
-- This is User Defined Table Type Variable
Declare #MyTypeDataType ContType
-- You will pass value to this variable from Front End
Insert into #MyTypeDataType values(1),(2),(3);
-- From Front end you will pass the
-- selected values to "Table Type Variable" and
-- also to a "Varchar" Variable
Declare #Type as Varchar(20);
SET #Type = '1,2,3';
SELECT X.* FROM
(
-- This query will get all persons,
-- who have any one Type u want to Search...
SELECT C.*,CTT.ContactType, CTT.ContactTypeId FROM Contact C
INNER JOIN ContactWithType CT
ON C.ContactId = CT.ContactId
INNER JOIN ContactType CTT
ON CTT.ContactTypeId = CT.ContactTypeId
WHERE #Type LIKE '%' + CAST( CT.ContactTypeId AS VARCHAR(MAX)) + '%'
) X
INNER JOIN
(
-- This will count the Record of each Person,
-- how many time a persons record exists..
SELECT C.ContactId, COUNT(C.ContactId) AS Total
FROM Contact C
INNER JOIN ContactWithType CT
ON C.ContactId = CT.ContactId
INNER JOIN ContactType CTT
ON CTT.ContactTypeId = CT.ContactTypeId
WHERE #Type LIKE '%' + CAST( CT.ContactTypeId AS VARCHAR(MAX)) + '%'
GROUP BY C.ContactId
)Y
ON X.ContactId = Y.ContactId
-- Filter persons
AND Y.Total = (SELECT COUNT(*) FROM #MyTypeDataType)
I would like to recommend to use split function for your query to filter ContactTypes. For example, when in your form someone check Property Owner and Tenant (contactType = 1, 2) or so on, then you can pass it to your stored proc as such
#ContactTypes varchar(max) = '1,2'
Then you can use one of the split string function that you need to create. You can refer to this excellent article (http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings).
I use the article function SplitStrings_Moden for simple string split.
Then you can use it like in your stored proc like this.
And ContactType in (select [item] from SplitStrings_Moden(#ContactTypes , ','))
As for performance wise, the example given return a table of string column which in your case, you could cast it to int for better for performance. But i guess you might to test it on your dataset if the performance is reasonable without the casting.
I would recommend using xml datatype for this. You can find more information here.
Use XML as input variable to an SP
i am trying to insert a statement contains WHERE from two different tables :
the table i want to insert into is dbo.order
the other two tables are :
dbo.users. user_id.
dbo.packages. package_id.
another order field "notes".
the statement i tried is
insert into dbo.order
(customer_id,package_id,notes)
Select user_id,Package_ID
from
dbo.users,dbo.packages
where
username = 'bader' AND package_name = 'beginner','notes value here';
any suggestions ?
There's no obvious join here so you'll get the cartesian product of Bader orders and beginner packages. Not sure what the notes value should be. If its a literal you can just include it in the select clause.
insert into dbo.order
(customer_id,package_id,notes)
Select
user_id,Package_ID , 'notes value here'
from
dbo.users,dbo.packages
where
username = 'bader' AND package_name = 'beginner';
insert into dbo.order
(customer_id,package_id,notes)
Select user_id, Package_ID, 'notes value here'
from
dbo.users, dbo.packages
where
username = 'bader' AND package_name = 'beginner';