My SQL knowledge is pretty limited and this seems like something that should be easy, but I can't figure it out.
I have two queries that I run with the same where clause. Previously, I've pasted the number in the where clause twice. I thought there had to be an easier way so I found that you can do variables.
My problem is when declaring the variable in the first query, it forgets it and doesn't run it for the second query. The terminology may be off on a lot of what I've explain, but the simple query below should explain it better. The second query fails and says
must declare the scalar variable #p_repid
which I have declared in the first query.
DECLARE #p_repid int=3427115
select fldRBuddyId, count(fldRBuddyId) "Repeats"
from tblMsgsOnAir_Type8 typ8
where fldCBuddyId = #p_repid
group by fldRBuddyID
having count(fldRBuddyId) > 1
order by "Repeats" desc
go
select FLDREPID,moa.FLDTGBID,tt.FLDNAME, count(*) "Count"
from TBLMSGSONAIR_1 moa
join TBLTOWERS_1 tt on moa.FLDTGBID=tt.FLDTGBID
where fldrepid = #p_repid
group by FLDREPID,moa.FLDTGBID,tt.FLDNAME
order by "Count" desc
go
Thanks in advance for any help.
Remove the GO between the two statements. That's MS SQL Server's batch separator.
If you use "GO" command all declared variables are gone.
Try removing the "GO" which is in the middle.
Related
I have a really simple SQL Server query that doesn't return a value. I'd like to see my query return a single row set with a space in it, but I can't seem to get it after a lot of time trying and searching! So, I've got to be doing something wrong and I really feel kind of dumb for having to post such a simple thing, but I can't seem to get it...
Here's the Select:
Select Session from Logins where Session = '123'
In my table the value '123' does not exist under the Session column...
So, I need this simple query to return a space as the value and not return an empty row set.
I've tried ISNULL, COALESCE and the little known IFNULL, all to no effect.
Interestingly, if I remove the where clause from the query it returns multiple rows correctly, none of them as nulls - as SQL Server should do, but when I put in my where clause in I get an empty row set. What I can't understand is why!
All you SQL Server gurus out there, could you please help me to develop a query that returns one column with one row that has a space in it when there is no return set for a where clause?
Thanks in advance,
Usually, you would want to perform this sort of logic in the client side rather than directly in the query.
But here is one way you can do it in pure SQL by putting your query in a CTE. Not sure if the CTE will get run twice though.
with cte as (
select session
from Logins
where session = '123'
)
select session
from cte
union all
select ' ' as session
where not exists (select null from cte)
I am going round in circles with a bit of SQL and would appreciate some help.
I've looked up creating temp tables, nested Select statements (where advice seems to be to avoid these like the plague) and various uses of Case statements but I can't seem to find a solution that works. I'd say I'm beginner level for SQL.
I have a table with 10 relevant records. The query that works to return all the relevant entries in the table is:
SELECT
TblServAct.ServActId
,TblServAct.ServActName
FROM TblServAct
WHERE TblServAct.ServActExclude IS NULL
ORDER BY TblServAct.ServActName
Here is where I run into problems:
When the parameter (#YESNOActivity) = Yes, I want all the rows in the table to be returned. I have managed to do this with a CASE statement
...however when the parameter (#YESNOActivity) = No, I want ONLY ONE row to be returned which doesn't actually exist in the table (and should not be inserted into the actual table). The values that I need to insert are: ServActId = 101 and ServActName = 'Select YES in Parameter2 to filter by Service Activity'
For background, the reason I am doing this is because I have found SSRS report parameters to be especially difficult to conditionally format. I want to use the dataset above to return a message in a parameter (lets call it parameter2) that the user needs to select yes in (#YESNOActivity) in order to see the full selection list in parameter2.
If I can get this to work I can see lots of potential for re-use so all advice appreciated
Thanks
Eileen
I believe this should do the job, just include your parameter in the WHERE clause and UNION it with your own row of data.
SELECT
TblServAct.ServActId
,TblServAct.ServActName
FROM TblServAct
WHERE TblServAct.ServActExclude IS NULL
AND #YESNOActivity = 'Yes'
UNION ALL
SELECT
ServActId = 101
,ServActName = 'Select YES in Parameter2 to filter by Service Activity'
WHERE #YESNOActivity = 'No'
ORDER BY TblServAct.ServActName
One way is to use this query:
SELECT
TblServAct.ServActId
,TblServAct.ServActName
FROM TblServAct
WHERE TblServAct.ServActExclude IS NULL
AND 'Yes' = #YESNOActivity
UNION ALL
SELECT
101 AS ServActId
,'Select YES in Parameter2 to filter by Service Activity' AS ServActName
WHERE 'No' = #YESNOActivity
ORDER BY TblServAct.ServActName
Another way would be to create two data flows and use your variable in a constraint to send the processing to one or the other.
A third way would be to put an expression on the SQL command and use your variable to switch between two SQL statements.
I remember reading a while back that randomly SQL Server can slow down and / or take a stupidly long time to execute a stored procedure when it is written like:
CREATE PROCEDURE spMyExampleProc
(
#myParameterINT
)
AS
BEGIN
SELECT something FROM myTable WHERE myColumn = #myParameter
END
The way to fix this error is to do this:
CREATE PROCEDURE spMyExampleProc
(
#myParameterINT
)
AS
BEGIN
DECLARE #newParameter INT
SET #newParameter = #myParameter
SELECT something FROM myTable WHERE myColumn = #newParameter
END
Now my question is firstly is it bad practice to follow the second example for all my stored procedures? This seems like a bug that could be easily prevented with little work, but would there be any drawbacks to doing this and if so why?
When I read about this the problem was that the same proc would take varying times to execute depending on the value in the parameter, if anyone can tell me what this problem is called / why it occurs I would be really grateful, I cant seem to find the link to the post anywhere and it seems like a problem that could occur for our company.
The problem is "parameter sniffing" (SO Search)
The pattern with #newParameter is called "parameter masking" (also SO Search)
You could always use the this masking pattern but it isn't always needed. For example, a simple select by unique key, with no child tables or other filters should behave as expected every time.
Since SQL Server 2008, you can also use the OPTIMISE FOR UNKNOWN (SO). Also see Alternative to using local variables in a where clause and Experience with when to use OPTIMIZE FOR UNKNOWN
I want to run a SELECT statement and I want execute a DELETE statement for the same row and the read result be respond by the SQL Server.
WITH cte AS (
SELECT *
FROM <mytable>
WHERE key = <mykey>)
DELETE cte
OUTPUT deleted.*;
There are many ways to skin this cat. I often preffer the one posted because is very readable. It clearly separates the SELECT into its own query expression, allowing for easily created complex queries. It deletes exactly the query result. It outputs the deleted rows.
The following is also perfectly valid and easier for simple WHERE clauses:
DELETE <mytable>
OUTPUT deleted.*
WHERE key = <mykey>;
I have a requirement to update a column with multiple values. The query looks like below.
Update table1 set column1 = (
select value from table2 where table1.column0 = table2.coulmn
)
Is there any generalised stored procedure for a requirement like the above?
short of creating a statement as a string and using the "execute" statement, I don't know of one. Generally "execute" is frowned on as it's a potential injection attack point.
Why would you want to update one table with information that is easily available in another? Seems like you are just guaranteeing that you are going to have to run this query every single time you perform an update, insert or delete against the camsnav table. Otherwise how are you going to keep them in sync?
Also, if you cannot guarantee that the sub-query will return exactly one row, it is probably safer to use the SQL Server-specific and proprietary update format:
UPDATE f SET nav = n.nav
FROM camsfolio AS f
INNER JOIN camsnav AS n
ON f.schcode = n.schcode;
SQL Server doesn't use "generalised stored procedures" for this kind of thing. It's up to you to build your own SP, composed using an appropriate parameterized UPDATE statement.