How to sum random rows column in where clause SQL - sql-server

I have a stored procedure that selects a number of random rows from a table based on a parameter and I need to run this in a loop so it constantly selects random rows until the sum of them is accepted
So far I haven't started the loop yet because I can't figure out how do i use sum of a column as a condition
GO
IF OBJECT_ID('dbo.spx_SELECT_RandomLocalizacoes') IS NOT NULL
DROP PROCEDURE spx_SELECT_RandomLocalizacoes
GO
CREATE PROCEDURE spx_SELECT_RandomLocalizacoes
#Localizacoes_Max int,
#Filtro int,
#Armazem int
AS
BEGIN
SET NOCOUNT ON
SELECT TOP (#Localizacoes_Max) * FROM xInventario
WHERE Armazem = #Armazem AND SUM(Quantidade) > #Filtro
ORDER BY newid()
END
The final result should be a procedure that returns me the rows that obey the condition
EDIT:
I forgot to add that, I have to return the select statement with the random rows with the same seed so i can only do that query once

you can treat your query as a sub-query and SUM it, then apply whatever logic you are looking for
if (SELECT SUM(Randoms.YourField) FROM (SELECT TOP (#Localizacoes_Max) * FROM xInventario
WHERE Armazem = #Armazem AND SUM(Quantidade) > #Filtro
ORDER BY newid()) AS Randoms) = #Target
BEGIN
--do stuff
END

Related

Issue with SQL INSERT Trigger

I'm reaching out for some help on this trigger I'm trying to get working.
Basically this is what I'm trying to do.
We have DMS software that writes to a Database and on a particular INSERT value I want the trigger to fire.
This is an example of an INSERT statement that will get processed.
INSERT INTO DOCSADM.ACTIVITYLOG (CR_IN_USE,ACTIVITY_DESC,BILLED_ON,BILLABLE,PAGES,KEYSTROKES,
TYPE_TIME,ELAPSED_TIME,TYPIST,AUTHOR,START_DATE,ACTIVITY_TYPE,REF_DOCUMENT,REF_LIBRARY,APPLICATION,VERSION_LABEL,DOCNUMBER,SYSTEM_ID)
VALUES ('','DOCSFusion','1753-01-01','',0,0,0,0,1920,1920,'2020-08-26T10:17:56',**115**,0,-1,1173,'',75,3252)
but I only want the trigger to fire when we see a value of 115 for the bold section in the INSERT statement (the Activity_type value).
For all other values that re not 115 I don't want to do anything.
This is what I have so far:
CREATE TRIGGER BW_TRIGGER
ON DOCSADM.ACTIVITYLOG
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--Declare some variable and set it as a value of 115.
--Example:
DECLARE #AlogType int = (SELECT I.ACTIVITY_TYPE FROM DOCSADM.ACTIVITYLOG A, INSERTED I) --This is the value you are looking for regarding the DM client/Matter actitivty type.
DECLARE #AlogDesc varchar(32) = (Select i.ACTIVITY_DESC from docsadm.ACTIVITYLOG A, INSERTED I)
--Next, you should have a fork or path in your trigger to determine how it proceeds.
--Path 1: The #AlogType value matches the inserted value so you want to process the rest of the trigger. Example path – “ProcessTrigger:”
--Path 2: The #AlogType value does NOT match the inserted value, you want to exit the trigger. Example Path – “ExitTrigger:”
IF #AlogType <> 115
GOTO TriggerExit;
ELSE
Begin
/*Create first temp table to collect insert values*/ --This table will have the SysID Value and the corresponding docnumber for the items you want.
--You can add whatever other values you think you need.
CREATE TABLE #TempSet1
(
AlogsysID INT,
Docnum INT,
AlogDate Varchar(64),
AlogTypist INT,
AlogAuthor INT,
AlogDesc varchar(32),
ALOGVER varchar(10),
ALOG_MATTER INT
)
INSERT INTO #TempSet1 (AlogsysID,Docnum,AlogDate,AlogTypist,AlogAuthor, ALOG_MATTER)
--SELECT  You SELECT STATEMENT WILL GO HERE MODIFIED TO POPULATE THE TABLE WITH THE DOCNUMBERS YOU WANT!!
select top 1 System_id, docnumber, LAST_ACCESS_DATE, TYPIST, AUTHOR, MATTER from docsadm.PROFILE where EXISTS (SELECT CLIENT.SYSTEM_ID FROM DOCSADM.CLIENT INNER JOIN DOCSADM.MATTER ON MATTER.CLIENT_ID = CLIENT.SYSTEM_ID
WHERE MATTER.SYSTEM_ID =#AlogDesc OR INH_LUP_SEC_FROM IS NULL OR INH_LUP_SEC_FROM = 0) AND MATTER=#AlogDesc
/*Set variable #SysID as the LASTKEY value -1. This will be used to set the SysID column on the #TempSet table*/
--DECLARE #SysID INT = (SELECT LASTKEY FROM DOCSADM.SEQ_SYSTEMKEY) -1;
/*Set the SysID value for every row on the #TempSet1 table as the #SysID variable +1*/
--UPDATE #TempSet1
--SET #SysID = AlogsysID = #SysID + 1
--Your #TempSet should now be set with ALL of the System_IDs and Docnumbers necessary for your insert!!!!—
--Verify this by doing a select against the #TempSet1 Table
SELECT * FROM #TempSet1;
--Next you need to set the SystemID to the correct value for future processing. To do this, we need to get a total count from the #TempSet table.
/*Set a variable to update the NEXTKEY value on the DOCSADM.SEQ_SYSTEMKEY table. The NEXTKEY value is used for the SYSTEM_ID field*/
--DECLARE #SeqUpdateCount INT = (SELECT COUNT(*) FROM #TempSet1);
/*Update the LASTKEY Value on the SEQ_SYSTEMKEY table to the next available value for DM.*/
--UPDATE DOCSADM.SEQ_SYSTEMKEY SET LASTKEY = LASTKEY+#SeqUpdateCount
--If you have all the values you need in your temp table, you can now insert them into the ACTIVITYLOG table.
--INSERT INTO DOCSADM.ACTIVITY
--(SYSTEM_ID, DOCNUMBER, START_DATE, version, EXT,)
--SELECT
--AlogSysID,Docnum,GETUTCDATE(),BLAH, BLAH
--FROM #TableSet1
INSERT INTO DOCSADM.ACTIVITYLOG
(SYSTEM_ID,
DOCNUMBER,
START_DATE,
TYPIST,
AUTHOR,
ACTIVITY_DESC,
VERSION_LABEL,
ACTIVITY_TYPE)
SELECT
AlogsysID, Docnum,AlogDate,AlogTypist, AlogAuthor, ALOG_MATTER, '',115
FROM #TempSet1;
--Now you need to Drop the Temp Table
DROP TABLE #TempSet1
--Go to the other half of your path above to exit the trigger.
END
TriggerExit:
END
Go
but when I try to run any INSERT statement on this table I get this error message. It doesn't matter if the activity_type has a value of 115 or not
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I know the issue is with this section of the trigger:
INSERT INTO #TempSet1 (AlogsysID,Docnum,AlogDate,AlogTypist,AlogAuthor, ALOG_MATTER)
--SELECT  You SELECT STATEMENT WILL GO HERE MODIFIED TO POPULATE THE TABLE WITH THE DOCNUMBERS YOU WANT!!
SELECT TOP 1
System_id
, docnumber
, LAST_ACCESS_DATE
, TYPIST
, AUTHOR
, MATTER
FROM docsadm.PROFILE
WHERE EXISTS (SELECT CLIENT.SYSTEM_ID
FROM DOCSADM.CLIENT
INNER JOIN DOCSADM.MATTER
ON MATTER.CLIENT_ID = CLIENT.SYSTEM_ID
WHERE MATTER.SYSTEM_ID =#AlogDesc
OR INH_LUP_SEC_FROM IS NULL
OR INH_LUP_SEC_FROM = 0)
AND MATTER=#AlogDesc
It's the SELECT statement that is causing it to fail.
I know that this statement will bring back multiple rows but I only need the value from one of them so I can use this value for my INSERT. I though having the "select top 1" would do this for me but it's not working like I think it should. What am I missing?
If I had to guess I would say your problem is here:
DECLARE #AlogType int = (SELECT I.ACTIVITY_TYPE FROM DOCSADM.ACTIVITYLOG A, INSERTED I) --This is the value you are looking for regarding the DM client/Matter actitivty type.
DECLARE #AlogDesc varchar(32) = (Select i.ACTIVITY_DESC from docsadm.ACTIVITYLOG A, INSERTED I)
How are ACTIVITYLOG and INSERTED joined in the above ? without a where it would be a CROSS JOIN. Why do you even drag ACTIVITYLOG into it, you can simply use INSERTED. Also please try to stop using implicit joins ( I can see that later down the script you use the proper, more verbose join syntax)
TRY:
DECLARE #AlogType int = (SELECT I.ACTIVITY_TYPE FROM INSERTED I) --This is the value you are looking for regarding the DM client/Matter actitivty type.
DECLARE #AlogDesc varchar(32) = (Select i.ACTIVITY_DESC from INSERTED I)
Be careful that this will work with single inserts only. When you do batched inserts the INSERTED is a table containing multiple rows and you will run into issues again.

Pulling Values From Temp Table After An Iteration

I'm querying for the total sizes of recent data in certain databases.
I create a table containing the DBs to be queried then iterate over it to get the DB names and total number of times to run the iteration.
I then create a temptable where the needed data will be inserted into.
I run the iteration to grab the information and push it into the temptable for each database.
After the iteration finishes I'm not able to pull the values from this newly created table.
I wrote a little comment next to each portion of code explaining what I'm trying to do and what I expect to happen.
/*check if the #databases table is already present and then drop it*/
IF OBJECT_ID('tempdb..#databases', 'U') IS NOT NULL
begin
drop table #databases;
end
select ArtifactID into #databases from edds.eddsdbo.[Case]
where name like '%Review%'
/*Once this first statement has been run there will now be a
number column that is associated with the artificatID. Each database has an area that is
titled [EDDS'artifactID']. So if the artifactID = 1111111 then the DB would
be accessed at [EDDS1111111]*/
declare #runs int = 1; /*this will track the number of times iterated
over the result set*/
declare #max int = 0; /*this will be the limit*/
declare #databasename sysname='' /*this will allow the population of each
database name*/
/*check if your temp table exists and drop if necessary*/
IF OBJECT_ID('tempdb..#temptable', 'U') IS NOT NULL
begin
drop table #temptable;
end
/*create the temp table as outside the loop*/
create table #temptable(
fileSize dec,
extractedTextSize dec
)
while #runs<=#max
begin
select #max=count(*) from #databases;
/*the #max is now the number of databases inserted in to this table*/
/*This select statement pulls the information that will be placed
into the temptable. This second statment should be inside the loop. One time
for each DB that appeared in the first query's results.*/
/*begin the loop by assigning your database name, I don't know what the
column is called so I have just called it databasename for now*/
select top 1 #databasename = ArtifactID from #databases;
/*generate your sql using the #databasename variable, if you want to make
the database and table names dynamic too then you can use the same formula*/
insert into #temptable
select SUM(fileSize)/1024/1024/1024, SUM(extractedTextSize)/1024/1024
FROM [EDDS'+cast(#databasename as nvarchar(128))+'].[EDDSDBO].[Document] ed
where ed.CreatedDate >= (select CONVERT(varchar,dateadd(d,-
(day(getdate())),getdate()),106))'
/*remove that row from the databases table so the row won't be redone
This will take the #max and lessen it by one*/
delete from #databases where ArtifactID=#databasename;
/* Once the #max is less than 1 then end the loop*/
end
/* Query the final values in the temp table after the iteration is complete*/
select filesize+extractedTextSize as Gigs from #temptable
When that final select statement runs to pull values from #temptable the response is a single gigs column(as expected) but the table itself is blank.
Something is happening to clear the data out of the table and I'm stuck.
I'm not sure if my error is in syntax or a general error of logic but any help would be greatly appreciated.
Made a few tweaks to formatting but main issue is your loop would never run.
You have #runs <= #max, but #max = 1 and #runs = 0 at start so it will never loop
To fix this you can do a couple different things but I set the #max before loop, and in the loop just added 1 to #runs each loop, since you know how many you need #max before loop runs, and just add it to number of runs and do your compare.
But one NOTE there are much better ways to do this then the way you have. Put identity on your #databases table, and in your loop just do where databaseID = loopCount (then you dont have to delete from the table)
--check if the #databases table is already present and then drop it
IF OBJECT_ID('tempdb..#databases', 'U') IS NOT NULL
drop table #databases;
--Once this first statement has been run there will now be a number column that is associated with the artificatID. Each database has an area that is
-- titled [EDDS'artifactID']. So if the artifactID = 1111111 then the DB would be accessed at [EDDS1111111]
select ArtifactID
INTO #databases
FROM edds.eddsdbo.[Case]
where name like '%Review%'
-- set to 0 to start
DECLARE #runs int = 0;
--this will be the limit
DECLARE #max int = 0;
--this will allow the population of each database name
DECLARE #databasename sysname = ''
--check if your temp table exists and drop if necessary
IF OBJECT_ID('tempdb..#temptable', 'U') IS NOT NULL
drop table #temptable;
--create the temp table as outside the loop
create table #temptable(
fileSize dec,
extractedTextSize dec
)
-- ***********************************************
-- Need to set the value your looping on before you get to your loop, also so if you dont have any you wont do your loop
-- ***********************************************
--the #max is now the number of databases inserted in to this table
select #max = COUNT(*)
FROM #databases;
while #runs <= #max
BEGIN
/*This select statement pulls the information that will be placed
into the temptable. This second statment should be inside the loop. One time
for each DB that appeared in the first query's results.*/
/*begin the loop by assigning your database name, I don't know what the
column is called so I have just called it databasename for now*/
select top 1 #databasename = ArtifactID from #databases;
/*generate your sql using the #databasename variable, if you want to make
the database and table names dynamic too then you can use the same formula*/
insert into #temptable
select SUM(fileSize)/1024/1024/1024, SUM(extractedTextSize)/1024/1024
FROM [EDDS'+cast(#databasename as nvarchar(128))+'].[EDDSDBO].[Document] ed
where ed.CreatedDate >= (select CONVERT(varchar,dateadd(d,- (day(getdate())),getdate()),106))
--remove that row from the databases table so the row won't be redone This will take the #max and lessen it by one
delete from #databases where ArtifactID=#databasename;
--Once the #max is less than 1 then end the loop
-- ***********************************************
-- no need to select from the table and change your max value, just change your runs by adding one for each run
-- ***********************************************
--the #max is now the number of databases inserted in to this table
select #runs = #runs + 1 --#max=count(*) from #databases;
end
-- Query the final values in the temp table after the iteration is complete
select filesize+extractedTextSize as Gigs from #temptable
This is second answer, but its alternative to like I mentioned in above and cleaner to post to post as an alternative answer to keep them seperate
This is a better way to do your looping (not fully tested out yet so you will have to verify).
But instead of deleting from your table just add an ID to it and loop through it using that ID. Way less steps and much cleaner.
--check if the #databases table is already present and then drop it
IF OBJECT_ID('tempdb..#databases', 'U') IS NOT NULL
drop table #databases;
--create the temp table as outside the loop
create table #databases(
ID INT IDENTITY,
ArtifactID VARCHAR(20) -- not sure of this ID's data type
)
--check if your temp table exists and drop if necessary
IF OBJECT_ID('tempdb..#temptable', 'U') IS NOT NULL
drop table #temptable;
--create the temp table as outside the loop
create table #temptable(
fileSize dec,
extractedTextSize dec
)
--this will allow the population of each database name
DECLARE #databasename sysname = ''
-- initialze to 1 so it matches first record in temp table
DECLARE #LoopOn int = 1;
--this will be the max count from table
DECLARE #MaxCount int = 0;
--Once this first statement has been run there will now be a number column that is associated with the artificatID. Each database has an area that is
-- titled [EDDS'artifactID']. So if the artifactID = 1111111 then the DB would be accessed at [EDDS1111111]
-- do insert here so it adds the ID column
INSERT INTO #databases(
ArtifactID
)
SELECT ArtifactID
FROM edds.eddsdbo.[Case]
where name like '%Review%'
-- sets the max number of loops we are going to do
select #MaxCount = COUNT(*)
FROM #databases;
while #LoopOn <= #MaxCount
BEGIN
-- your table has IDENTITY so select the one for the loop your on (initalize to 1)
select #databasename = ArtifactID
FROM #databases
WHERE ID = #LoopOn;
--generate your sql using the #databasename variable, if you want to make
--the database and table names dynamic too then you can use the same formula
insert into #temptable
select SUM(fileSize)/1024/1024/1024, SUM(extractedTextSize)/1024/1024
-- dont know/think this will work like this? If not you have to use dynamic SQL
FROM [EDDS'+cast(#databasename as nvarchar(128))+'].[EDDSDBO].[Document] ed
where ed.CreatedDate >= (select CONVERT(varchar,dateadd(d,- (day(getdate())),getdate()),106))
-- remove all deletes/etc and just add one to the #LoopOn and it will be selected above based off the ID
select #LoopOn += 1
end
-- Query the final values in the temp table after the iteration is complete
select filesize+extractedTextSize as Gigs
FROM #temptable

Cursor to auto insert Roll Numbers in student table

How to go about auto populating student's roll number column in ascending order from 1,2,3... and so on on assign button click in the form ?
TABLE
How the cursor will be invoked?
I'm using stored procedures for all database operations.
SAMPLE CODE
declare #studID int
declare rollCursor CURSOR FOR
select * from TESTING
OPEN rollCursor
If you want a single StudentId, just write in your procedure
-- Where #StudendId will be parameter to your stored procedure
SELECT * FROM TESTING
WHERE StudId = #StudendId
Here is how you can use CURSOR. But note, CURSOR have performance issues. So use it rarely.
DECLARE #StudId INT
DECLARE #FName VARCHAR(50)
DECLARE #ROLL INT
-- Here you declare which all columns you need to loop in Cursor
DECLARE rollCursor CURSOR FOR
select * from TESTING
WHERE StudId = #StudendId
ORDER BY StudId;
OPEN rollCursor
-- Loop starts from here
FETCH NEXT FROM rollCursor
INTO #StudId,#FName,#ROLL
WHILE ##FETCH_STATUS = 0
BEGIN
-- Select studentid one by one from the table
SELECT * FROM TESTING
WHERE StudId = #StudId
-- Fetches next record and increments the loop
FETCH NEXT FROM rollCursor
INTO #StudId,#FName,#ROLL
END
CLOSE rollCursor;
DEALLOCATE rollCursor;
EDIT : 1 (Getting Row number for table)
If you need the result according to the roll then use the below query
-- This will bring you the records with roll number in ascending order
-- If you want in descending order just change ASC to DESC
SELECT studid,Fname,ROW_NUMBER() OVER(ORDER BY roll ASC) roll
FROM StudId
EDIT : 2 (Create identity field)
You need to set roll number column as Identity field, ie a column with an integer value which automatically increments value on new insertions.
Once you set the roll number column as Identity field, try with the below inserts
INSERT INTO TESTING(StudId,Fname)VALUES(10,'A')
INSERT INTO TESTING(StudId,Fname)VALUES(10,'A')
You will not select or include the roll number column in insert. It will automatically increment.
Click here to view more on identity field

Stored Procedure for SQL Server

I have written this stored procedure and it executes but it doesn't update the customer. The question is: Create a procedure named prc_cus_balance_update that will take the invoice number as a parameter and update the customer balance.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE PRC_CUS_BALANCE_UPDATE3
#INV_NUMBER INT
AS
BEGIN
DECLARE #CUS_CODE INT
SELECT #CUS_CODE=CUS_CODE
FROM INVOICE
WHERE #INV_NUMBER=INV_NUMBER
UPDATE CUSTOMER
SET CUS_BALANCE=CUS_BALANCE +
(SELECT INV_TOTAL FROM INVOICE WHERE #INV_NUMBER=INV_NUMBER)
WHERE #CUS_CODE=CUS_CODE
END
GO
While developing, I'd put in some "extras" to figure out what is going on.
Pseudo code below.
You want to make sure you found a matching row.
And you want to make sure at least one row was actually updated.
I'm NOT saying the code below is "production ready". But will show the concepts.
CREATE PROCEDURE PRC_CUS_BALANCE_UPDATE3
#INV_NUMBER INT
AS
BEGIN
DECLARE #CUS_CODE INT
DECLARE #MYROWCOUNT INT
SELECT #CUS_CODE=CUS_CODE
FROM INVOICE
WHERE #INV_NUMBER=INV_NUMBER
if(Not(#CUS_CODE IS NULL))
BEGIN
SET NOCOUNT OFF
UPDATE CUSTOMER
SET CUS_BALANCE=CUS_BALANCE +
(SELECT INV_TOTAL FROM INVOICE WHERE #INV_NUMBER=INV_NUMBER)
WHERE #CUS_CODE=CUS_CODE
select #MYROWCOUNT = ##ROWCOUNT
if(#MYROWCOUNT <=0)
BEGIN
print 'No row updated. :<'
END
SET NOCOUNT OFF
END
ELSE
BEGIN
print "#CUS_CODE match not found."
END
END
GO
Try putting some better bulletproofing in. Multiple rows, null values, and the like, can all cause problems with how you currently have it. Here's a stab at it, without me knowing the specifics of your data model (it may not be appropriate to sum together the totals from invoices, I'm just saying you could have multiple rows and need to deal with that).
CREATE PROCEDURE PRC_CUS_BALANCE_UPDATE3
#INV_NUMBER INT
AS
BEGIN
DECLARE #CUS_CODE INT
SELECT
TOP 1 #CUS_CODE = CUS_CODE
FROM
INVOICE
WHERE
INV_NUMBER=#INV_NUMBER
IF #CUS_CODE IS NOT NULL
BEGIN
UPDATE
CUSTOMER
SET
CUS_BALANCE = ISNULL(CUS_BALANCE, 0.0) +
ISNULL(
(SELECT
SUM(INV_TOTAL)
FROM
INVOICE
WHERE
#INV_NUMBER = INV_NUMBER),
0.0)
WHERE
CUS_CODE = #CUS_CODE
END
END
GO

select TOP (all)

declare #t int
set #t = 10
if (o = 'mmm') set #t = -1
select top(#t) * from table
What if I want generally it resulted with 10 rows, but rarely all of them.
I know I can do this through "SET ROWCOUNT". But is there some variable number, like -1, that causing TOP to result all elements.
The largest possible value that can be passed to TOP is 9223372036854775807 so you could just pass that.
Below I use the binary form for max signed bigint as it is easier to remember as long as you know the basic pattern and that bigint is 8 bytes.
declare #t bigint = case when some_condition then 10 else 0x7fffffffffffffff end;
select top(#t) *
From table
If you dont have an order by clause the top 10 will just be any 10 and optimisation dependant.
If you do have an order by clause to define the top 10 and an index to support it then the plan for the query above should be fine for either possible value.
If you don't have a supporting index and the plan shows a sort you should consider splitting into two queries.
im not sure I understand your question.
But if you sometimes want TOP and other times don't just use if / else construct:
if (condition)
'send TOP
SELECT TOP 10 Blah FROM...
else
SELECT blah1, blah2 FROM...
You can use dynamic SQL (but I, personally, try to avoid dynamic SQL), where you create a string of the statement you want to run from conditions or parameters.
There's also some good information here on how to do it without dynamic SQL:
https://web.archive.org/web/20150520123828/http://sqlserver2000.databases.aspfaq.com:80/how-do-i-use-a-variable-in-a-top-clause-in-sql-server.html
declare #top bigint = NULL
declare #top_max_value bigint = 9223372036854775807
if (#top IS NULL)
begin
set #top = #top_max_value
end
select top(#top) *
from [YourTableName]
a dynamic sql version isn't that's hard to do.
CREATE PROCEDURE [dbo].[VariableTopSelect]
-- Add the parameters for the stored procedure here
#t int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #sql nvarchar(max)
if (#t=10)
begin
set #sql='select top (10) * from table'
end
else
begin
set #sql='select * from table'
end
exec sp_executesql #sql
END
with this sp, if they send 10 to the sp, it'll select the top 10, otherwise it'll select all.
The best solution I've found is to select the needed columns with all of your conditions into a temporary table, then do your conditional top:
DECLARE #TempTable TABLE(cols...)
INSERT INTO #TempTable
SELECT blah FROM ...
if (condition)
SELECT TOP 10 * FROM #tempTable
else
SELECT * FROM #tempTable
This way you follow DRY, get your conditional TOP, and are just as easy to read.
Cheers.
It is also possible with a UNION and a parameter
SELECT DISTINCT TOP 10
Column1, Column2
FROM Table
WHERE #ShowAllResults = 0
UNION
SELECT DISTINCT
Column1, Column2
FROM Table
WHERE #ShowAllResults = 1
I might be too late now, or getting too old
But I solved that by using Top(100)Percent
This goes around all complexities
Select Top(100)Percent * from tablename;
Use the statement "SET ROWCOUNT #recordCount" at the beginning of the result query.The variable "#recordCount" can be any positive integer. It should be 0 to return all records.
that means , "SET ROWCOUNT 0" will return all records and "SET ROWCOUNT 15" will return only the TOP 15 rows of result set.
Drawback can be the Performance hit when dealing with large number of records. Also the SET ROWCOUNT will be effective throughout the scope of execution of the whole query.

Resources