Abstract: I have a table with multiple columns and I am trying to implement a while (loop) function to all the columns to pull out the average of each column.
I coded this to attribute a number to each column (to ease the possibility of an incremental method)
Declare #tablename as varchar(128)
Declare #column1 as varchar(128)
Delect #tablename = 'MOMENTUM_Results'
Select #column1 = sc.name
from sysobjects as so inner join syscolumns as sc on so.id = sc.id
where so.name = #tablename and sc.colid = 2
When I print this code it prints the name of the column based on the number I put from 1 to 122.
Code for the loop function:
WHILE ....
BEGIN
SET #SQL = 'SELECT AVG(MR.[' + #column1 + ']) From MOMENTUM_Quintile MQ
Left Join MOMENTUM_Returns MR on MQ.Mnemonic = MR.Mnemonic WHERE MQ.[' + #column1 + '] = 1'
END
But I definitely do not have a clue how to integrate this function into the loop so the function goes through all the columns one by one, therefore looking for some advice..
Thank you!
R.H.
Can you not just move your SELECT from sys.Columns into the body of your WHILE loop to get the one you're after? Something like this...
DECLARE #TABLENAME AS VARCHAR(128);
DECLARE #COLUMN1 AS VARCHAR(128);
DECLARE #COUNTER INT;
SET #TABLENAME = 'MOMENTUM_Results';
SET #COUNTER = 1;
WHILE ....
BEGIN
SELECT #COLUMN1 = C.Name
FROM sys.Columns C
WHERE OBJECT_NAME(C.object_id) = #TABLENAME
AND C.column_id = #COUNTER
;
SET #SQL = 'SELECT AVG(MR.[' + #COLUMN1 + ']) From MOMENTUM_Quintile MQ
Left Join MOMENTUM_Returns MR on MQ.Mnemonic = MR.Mnemonic WHERE MQ.[' + #COLUMN1 + '] = 1';
... Other Stuff ...
SET #COUNTER = #COUNTER + 1;
END
;
Maybe I didn't properly understand your question, but if you already have everything written out you could just change the placement to select the column names you want.
Of course you can also add additional conditions to make sure you're getting matched columns, or columns by name, or whatever...
EDIT:
You asked about inserting the resultant query into a table. If you already have a table with a column ready to receive the query, then the answer is simple... In the body of your WHILE loop, after retrieving the desired query, simply add an INSERT command:
WHILE ....
BEGIN
SELECT #COLUMN1 = C.Name
FROM sys.Columns C
WHERE OBJECT_NAME(C.object_id) = #TABLENAME
AND C.column_id = #COUNTER
;
SET #SQL = 'SELECT AVG(MR.[' + #COLUMN1 + ']) From MOMENTUM_Quintile MQ
Left Join MOMENTUM_Returns MR on MQ.Mnemonic = MR.Mnemonic WHERE MQ.[' + #COLUMN1 + '] = 1';
INSERT INTO <mytable> (<querycolumn>) VALUES (#SQL);
... Other Stuff ...
SET #COUNTER = #COUNTER + 1;
If you need to create the table, you can do that in the head of the script, before declaring anything else, and do the same thing during the WHILE:
DECLARE #TABLENAME AS VARCHAR(128);
DECLARE #COLUMN1 AS VARCHAR(128);
DECLARE #COUNTER INT;
SET #TABLENAME = 'MOMENTUM_Results';
SET #COUNTER = 1;
CREATE TABLE <mytable> (<optional_column1>,<optional_column2>,<querycolumn>);
....
WHILE ....
BEGIN
SELECT #COLUMN1 = C.Name
FROM sys.Columns C
WHERE OBJECT_NAME(C.object_id) = #TABLENAME
AND C.column_id = #COUNTER
;
SET #SQL = 'SELECT AVG(MR.[' + #COLUMN1 + ']) From MOMENTUM_Quintile MQ
Left Join MOMENTUM_Returns MR on MQ.Mnemonic = MR.Mnemonic WHERE MQ.[' + #COLUMN1 + '] = 1';
INSERT INTO <mytable> (<querycolumn>) VALUES (#SQL);
... Other Stuff ...
SET #COUNTER = #COUNTER + 1;
First get all the column names in that table into a temporary table(#temp)
Get the count of all columns(#count_of_columns) in that temptable.
declare a variable #count=1
Declare while loop as While(#count<=#count_of_columns)
--> fetch the column name one after another inside this while loop using the following query
SET #column1=(select top 1 column1 from
(select Row_number()over (order by column1) as r_n_n, column1
from #temp) aa
where r_n_n >=#Count)
--> use your actual code here
--> increment the #count variable
set #count = #count + 1
Don't use loops or cursors, if you can avoid them. The devil of procedural thinking is pulling you away from the light of set based approaches deep into pain and misery!
I know the column names in advance, I just did it to ease the way I would loop through each column
NO! This is not easing the way but punishing the poor engine :-)
Is it this you are looking for?
CREATE TABLE dbo.Test(ID INT, VAl1 DECIMAL(14,4), Val2 DECIMAL(14,4), Val3 DECIMAL(14,4));
GO
INSERT INTO dbo.Test VALUES(1,1,10,100),(2,2,20,200),(3,3,30,300);
GO
SELECT AVG(Val1) AS Avg1,AVG(Val2) AS Avg2,AVG(Val3) AS Avg3
FROM dbo.Test;
GO
DROP TABLE dbo.Test;
The result
Avg1 Avg2 Avg3
2.000000 20.000000 200.000000
UPDATE
If you just want to be lazy and avoid typing, you might try something like this:
SELECT ',AVG(' + COLUMN_NAME + ') AS ' + QUOTENAME('AVG_' + COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='dbo' AND TABLE_NAME='Test'
FOR XML PATH('')
The result
,AVG(ID) AS [AVG_ID],AVG(VAl1) AS [AVG_VAl1],AVG(Val2) AS [AVG_Val2],AVG(Val3) AS [AVG_Val3]
With this trick you can build your hard coded statement quite easily :-)
Related
I was trying to create new tables using the identifier through a list.
DECLARE #Counter INT, #TableName NVARCHAR(20)
SET #Counter = 1
WHILE (#Counter <= 20)
BEGIN
SELECT #TableName = TableName FROM [dbo].[TableList] WHERE index = #Counter
SELECT * INTO [dbo].[#TableName.combine] FROM [dbo].[#TableName] t
LEFT JOIN [dbo].[cost] c ON t.x = c.y
SET #Counter = #Counter +1
END
And it keeps saying the object of [dbo].[#TableName] is invalid, but I already have [dbo].[#TableName] as a table.
I looked over the declare table variable, but [dbo].[#TableName] already existed in the database, how can I point to the table that I want?
You need to use dynamic SQL for this.
You can build one big query using STRING_AGG and then execute it
DECLARE #sql nvarchar(max);
SELECT #sql =
STRING_AGG(CAST('
SELECT *
INTO dbo.' + QUOTENAME(tl.TableName + '.combine') + '
FROM dbo.' + QUOTENAME(tl.TableName) + ' t
LEFT JOIN dbo.cost c ON t.x = c.y;
' AS nvarchar(max)), '
' )
FROM dbo.TableList tl;
EXEC sp_executesql #sql;
I am trying to update the results of my query into an existing table, as you can see it's a dynamic query and I don't know how to insert the update function in this code. When I insert it into the while function it sendS QUERY EXECUTED SUCCESSFULLY but there isn't any update..
I used this code for the dynamic query:
Declare #SQL AS VARCHAR(MAX)
DECLARE #TABLENAME AS VARCHAR(max);
DECLARE #COLUMN1 AS VARCHAR(max);
DECLARE #COUNTER INT;
SET #TABLENAME = 'MOMENTUM_Results';
SET #COUNTER = 2;
WHILE #COUNTER<=122
BEGIN
SELECT #COLUMN1 = C.Name
FROM sys.Columns C
WHERE OBJECT_NAME(C.object_id) = #TABLENAME
AND C.column_id = #COUNTER
;
SET #SQL = 'SELECT AVG(MR.[' + #COLUMN1 + ']) From MOMENTUM_Quintile MQ
Left Join MOMENTUM_Returns MR on MQ.Mnemonic = MR.Mnemonic WHERE MQ.[' + #COLUMN1 + '] = 5'
EXECUTE (#SQL)
SET #COUNTER = #COUNTER + 1;
END
To obtain these results:
And now I want to update a current table by using this code:
UPDATE MOMENTUM_Results
SET #COLUMN1 = #SQL
WHERE [MNEMONIC]='RANK_5';
The problem is I don't know where to place it in the 1st code.. or how to properly use it.. and finally here is the final format of the existing table (final result I want to obtain, in which I want to insert the query results in the row RANK_5)
Does someone have any clue?
PRINT RESULT:
DECLARE #avg as float;
SELECT #avg = AVG(MR.[2006-12-30]) From MOMENTUM_Quintile MQ
Left Join MOMENTUM_Returns MR on MQ.Mnemonic = MR.Mnemonic WHERE MQ.[2006-12-30] = 5;
UPDATE MOMENTUM_Results_new SET #COLUMN1 = #avg
WHERE [MNEMONIC]=RANK_5
EXECUTE RESULT:
Msg 137, Level 15, State 1, Line 6
Must declare the scalar variable "#COLUMN1".
Msg 137, Level 15, State 1, Line 6
Must declare the scalar variable "#COLUMN1".
Msg 137, Level 15, State 1, Line 6
Must declare the scalar variable "#COLUMN1".
Msg 137, Level 15, State 1, Line 6
Must declare the scalar variable "#COLUMN1".
Msg 137, Level 15, State 1, Line 6
Must declare the scalar variable "#COLUMN1".
#SQL is just a string, not the SELECT result of your dynamic query, so executing SET #COLUMN1 = #SQL is not probably what you want. Also when you execute dynamic sql you should consider the dynamic query and the rest of your code as two "parallel universes", the only thing that connects them is the common tables they may be editing. I would advise you declare a variable inside the dynamic query, assign to it the result of your AVG function and execute UPDATE in the dynamic too. Something like this:
Declare #SQL AS VARCHAR(MAX)
DECLARE #TABLENAME AS VARCHAR(max);
DECLARE #COLUMN1 AS VARCHAR(max);
DECLARE #COUNTER INT;
SET #TABLENAME = 'MOMENTUM_Results';
SET #COUNTER = 2;
WHILE #COUNTER<=122
BEGIN
SELECT #COLUMN1 = C.Name
FROM sys.Columns C
WHERE OBJECT_NAME(C.object_id) = #TABLENAME
AND C.column_id = #COUNTER
;
SET #SQL = 'DECLARE #avg float;
SELECT #avg = AVG(MR.[' + #COLUMN1 + ']) From MOMENTUM_Quintile MQ
Left Join MOMENTUM_Returns MR on MQ.Mnemonic = MR.Mnemonic WHERE MQ.[' + #COLUMN1 + '] = 5;
UPDATE '+#TABLENAME+' SET ' + #COLUMN1 + '= #avg
WHERE [MNEMONIC]=''RANK_5'''
EXECUTE (#SQL)
SET #COUNTER = #COUNTER + 1;
END
I may have syntax errors, I haven't tested it but you see my point
Your update statement only updates a variable.
SET #xyz = #abc will set the #xyz variable.
Try this:
UPDATE MOMENTUM_Results
SET COLUMN1 = #SQL
WHERE [MNEMONIC]='RANK_5';
(Note: I didn't see a "Column1" in your screenshot so I don't know if that column exists in your MOMENTUM_Results table. I might also be misunderstanding your question... are you wanting to update values in the MOMENTUM_Results table with a return value from the dynamic query? That's a different answer.
-EDIT-
Try changing your dynamic SQL to use "UPDATE ..." instead of "SELECT"
Something like
SET #SQL = 'UPDATE MOMENTUM_Results SET ' + #COLUMN1 + ' = AVG(MR.[' + #COLUMN1 + ']) From MOMENTUM_Quintile MQ
Left Join MOMENTUM_Returns MR on MQ.Mnemonic = MR.Mnemonic WHERE MQ.[' + #COLUMN1 + '] = 5 AND MOMENTUM_Results.MNEMONIC=''RANK_5'''
You may wish to build a single sql kind of
UPDATE mrs SET
col1 = x.co1, col2 = x.col2, ..
FROM MOMENTUM_Results mrs
CROSS JOIN
(SELECT AVG(case mq.col1 when 5 then mr.col1 end) col1, ..
FROM MOMENTUM_Quintile mq
LEFT JOIN MOMENTUM_Returns mr ON MQ.Mnemonic = mr.Mnemonic
AND (5 IN mq.col1, ..)
) x
WHERE mrs.[MNEMONIC]='RANK_5';
where col1, col2 .. are set dynamically.
I am using the cursor in my stored procedure; I am hoping to remove the cursor from my SP. Please help me come up with a solution for how to avoid the cursor statement to normal update statement with dynamic.
Example Below:
Update Tablename set columnname(variable) = value from table A join Table B on A.condition = B.Condition where name = 'Test'(variable) and age = 18(variable)
Update Tablename set columnname(variable) = value from table A join Table B on A.condition = B.Condition where name = 'kumar'(variable) and age = 19(variable)
Update Tablename set columnname(variable) = value from table A join Table B on A.condition = B.Condition where name = 'babu'(variable) and age = 30(variable)
This is how my cursor will work. 300 Combination dynamically pick the data from table and update into the main table
I am trying to take out the cursor, and update statement should work similar to this, instead of writing 300 update statements, I want to write one update where all the 300 combinations should execute.
Below is my code which needs this solution:
BEGIN
DECLARE #Type VARCHAR(100)
DECLARE #TargetColumn VARCHAR(100)
DECLARE #SourceColumn VARCHAR(100)
DECLARE #SQL varchar(max)
DECLARE a_cursor CURSOR STATIC
FOR
SELECT [Type],[SourceColumn],[TargetColumn] FROM ref.tblEdsMap
GROUP BY [Type],[SourceColumn],[TargetColumn]
OPEN a_cursor
FETCH NEXT FROM a_cursor INTO #Type,#SourceColumn,#TargetColumn
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = 'UPDATE GCT SET GCT.' + #TargetColumn + ' = map.[TargetValue]
from EdsMap map
JOIN Table GCT
ON GCT.' + #SourceColumn + ' = map.[SourceValue]
where map.[Type]=''' + #Type + ''' and map.SourceColumn=''' + #SourceColumn+ ''''
Exec (#SQL)
PRINT #SQL
FETCH NEXT FROM a_cursor INTO #Type,#SourceColumn,#TargetColumn
END
CLOSE a_cursor
DEALLOCATE a_cursor
END
Rather than use an explicit cursor or a cursor cleverly disguised as a while loop, I prefer row concatenation operations for this type of problem.
DECLARE #cmd NVARCHAR(MAX) = N'';
SELECT #cmd += N'
UPDATE GCT
SET GCT.' + QUOTENAME(TargetColumn) + ' = map.TargetValue
FROM dbo.EdsMap AS map
INNER JOIN dbo.Table AS GCT
ON GCT.' + QUOTENAME(SourceColumn) + ' = map.SourceValue
WHERE map.[Type] = ''' + [Type] + '''
AND map.SourceColumn = ''' + [SourceColumn]+ ''';'
FROM ref.tblEdsMap
GROUP BY [Type], SourceColumn, TargetColumn;
EXEC sp_executesql #sql;
When I've done these in the past, I usually make up a transaction to encompass every update that's needed. Something like this:
CREATE TABLE #targets ([Type] VARCHAR(255),[SourceColumn] VARCHAR(255),[TargetColumn] VARCHAR(255));
INSERT INTO #targets
( [Type], [SourceColumn], [TargetColumn] )
SELECT [Type],[SourceColumn],[TargetColumn] FROM ref.tblEdsMap
GROUP BY [Type],[SourceColumn],[TargetColumn];
DECLARE #sql VARCHAR(MAX);
SET #sql = 'BEGIN TRAN' + CHAR(10) + CHAR(13);
SELECT #sql = #sql +
'UPDATE GCT SET GCT.' + [TargetColumn] + ' = map.[TargetValue]
from EdsMap map
JOIN Table GCT
ON GCT.' + [SourceColumn] + ' = map.[SourceValue]
where map.[Type]=''' + [Type] + ''' and map.SourceColumn=''' + [SourceColumn]+ ''';' + CHAR(10) + CHAR(13)
FROM #targets
SELECT #sql = #sql + 'COMMIT TRAN'
PRINT #sql
Exec (#SQL)
The update statements are still the same, i.e., you get one update per combination. But now you're running as one transaction batch. You could potentially be fancier with the dynamic SQL, so that you had just one update statement, but in my experience, it's too easy to get bad updates that way.
Doing it this way may not be any faster than a cursor. You'd have to test to be sure. With the examples where I've used this approach, it has generally been a faster approach.
Try using a table variable along with a WHILE loop instead, like so:
BEGIN
DECLARE #Type VARCHAR(100)
DECLARE #TargetColumn VARCHAR(100)
DECLARE #SourceColumn VARCHAR(100)
DECLARE #SQL varchar(max)
DECLARE #SomeTable TABLE
(
ID int IDENTITY (1, 1) PRIMARY KEY NOT NULL,
Type varchar(100),
SourceColumn varchar(100),
TargetColumn varchar(100)
)
DECLARE #Count int, #Max int
INSERT INTO #SomeTable (Type, SourceColumn, TargetColumn)
SELECT [Type],[SourceColumn],[TargetColumn]
FROM ref.tblEdsMap
GROUP BY [Type],[SourceColumn],[TargetColumn]
SELECT #Count = 1, #Max = COUNT(ID)
FROM #SomeTable
WHILE #Count <= #Max
BEGIN
SELECT
#Type = Type,
#SourceColumn = SourceColumn,
#TargetColumn = TargetColumn
FROM #SomeTable
WHERE ID = #Count
-- Your code
SET #SQL = 'UPDATE GCT SET GCT.' + #TargetColumn + ' = map.[TargetValue]
from EdsMap map
JOIN Table GCT
ON GCT.' + #SourceColumn + ' = map.[SourceValue]
where map.[Type]=''' + #Type + ''' and map.SourceColumn=''' + #SourceColumn+ ''''
Exec (#SQL)
PRINT #SQL
SET #Count = #Count + 1
END -- while
END
Is there any other better way to perform this operation?
-- USE EXAMPLE: EXEC GetFirstIdInGap #tableName ='Employees',#column='IdEmployee'
CREATE PROCEDURE GetFirstIdInGap
(#tableName sysname,
#column sysname)
AS
IF #tableName IS NOT NULL and #column IS NOT NULL
BEGIN
DECLARE #col varchar(50), #col2 varchar(50)
SET #col = 'A.' + #column;
SET #col2 = 'A2.' + #column;
EXEC ('SELECT ISNULL((MIN('+#col+') - 1),(SELECT ISNULL(MAX('+#column+')+1,1) FROM '+#tableName+'))
AS '+#column+'
FROM '+#tableName+' AS a
LEFT JOIN '+#tableName+' AS a2
ON '+#col2+' = '+#col+' - 1
WHERE '+#col2+' IS NULL AND '+#col+' > 1');
END
GO
It gets the first free ID (if there are gaps) or the last one + 1 given a #tableName and #column. If there are no rows, it returns as the first ID = 1.
UPDATE:
For those who have asked about why do I need gaps of ID's, I am gonna explain my problem (although I didn't want to dig into it). I work with C# Winforms applications against other firmware applications which have serious memory restrictions. One of those restrictions is that I can only use a maximum code value of 65536. Those codes are equivalent of database ID's, and in some cases the firmware code had reached the value of 65536. That's why gap reusing would be wonderful for me.
t is your table
select
coalesce((select min(id)+1 from t mt where not exists(select 1 from t where id+1 = mt.id )), 1) firstgap
Here is an approach that doesn't require a numbers table (even one with more than 1,000 rows):
CREATE PROCEDURE dbo.GetFirstIdInGap_2
#table SYSNAME,
#column SYSNAME
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX) = N';WITH c AS
(
SELECT n = ' + #column + ',
rn = ROW_NUMBER() OVER (ORDER BY ' + #column + ')
FROM ' + #table + '
)
SELECT ' + #column + ' = 1 + COALESCE(
(SELECT MIN(c.n) FROM c INNER JOIN c AS n
ON n.rn = c.rn + 1 WHERE n.n - c.n > 1),
(SELECT MAX(c.n) FROM c),
0);';
EXEC sp_executesql #sql;
END
GO
t is your table
select min(isnull(id,0)+1) from t where isnull(id,0) + 1 not in (select isnull(id,0) from t)
I would like to search an entire MS SQL 2000 database for one value. This would be to aid development only. Keep that in mind when considering this question.
This will get all the table names and the column of the data type I'm looking for:
SELECT Columns.COLUMN_NAME, tables.TABLE_NAME
FROM INFORMATION_SCHEMA.Columns as Columns
JOIN INFORMATION_SCHEMA.TABLES as tables
On Columns.TABLE_NAME = tables.TABLE_NAME
WHERE Columns.DATA_TYPE = 'INT'
I was thinking something like this:
-- Vars
DECLARE #COUNTER INT
DECLARE #TOTAL INT
DECLARE #TABLE CHAR(128)
DECLARE #COLUMN CHAR(128)
DECLARE #COLUMNTYPE CHAR(128)
DECLARE #COLUMNVALUE INT
-- What we are looking for
SET #COLUMNTYPE = 'INT'
SET #COLUMNVALUE = 3
SET #COUNTER = 0
-- Find out how many possible columns exist
SELECT #TOTAL = COUNT(*)
FROM INFORMATION_SCHEMA.Columns as Columns
JOIN INFORMATION_SCHEMA.TABLES as tables
On Columns.TABLE_NAME = tables.TABLE_NAME
WHERE Columns.DATA_TYPE = #COLUMNTYPE
PRINT CAST(#TOTAL AS CHAR) + 'possible columns'
WHILE #COUNTER < #TOTAL
BEGIN
SET #COUNTER = #COUNTER +1
-- ADD MAGIC HERE
END
Any ideas?
UPDATE I recently found this tool that works quite well.
Since it is dev only (and probably doesn't have to be very elegant), how about using TSQL to generate a pile of TSQL that you then copy back into the query window and execute?
SELECT 'SELECT * FROM [' + tables.TABLE_NAME + '] WHERE ['
+ Columns.Column_Name + '] = ' + CONVERT(varchar(50),#COLUMNVALUE)
FROM INFORMATION_SCHEMA.Columns as Columns
INNER JOIN INFORMATION_SCHEMA.TABLES as tables
On Columns.TABLE_NAME = tables.TABLE_NAME
WHERE Columns.DATA_TYPE = #COLUMNTYPE
It won't be pretty, but it should work... an alternative might be to insert something like the above into a table-variable, then loop over the table-variable using EXEC (#Sql). But for dev purposes it probably isn't worth it...
I've found this script to be helpful... but as Marc noted, it wasn't really worth it. I've only used it a handful of times since I wrote it six months ago.
It only really comes in handy because there are a couple of tables in our dev environment which cause binding errors when you query them, and I always forget which ones.
BEGIN TRAN
declare #search nvarchar(100)
set #search = 'string to search for'
-- search whole database for text
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF nullif(object_id('tempdb..#tmpSearch'), 0) IS NOT NULL DROP TABLE #tmpSearch
CREATE TABLE #tmpSearch (
ListIndex int identity(1,1),
CustomSQL nvarchar(2000)
)
Print 'Getting tables...'
INSERT #tmpSearch (CustomSQL)
select 'IF EXISTS (select * FROM [' + TABLE_NAME + '] WHERE [' + COLUMN_NAME + '] LIKE ''%' + #search + '%'') BEGIN PRINT ''Table ' + TABLE_NAME + ', Column ' + COLUMN_NAME + ''';select * FROM [' + TABLE_NAME + '] WHERE [' + COLUMN_NAME + '] LIKE ''%' + #search + '%'' END' FROM information_schema.columns
where DATA_TYPE IN ('ntext', 'nvarchar', 'uniqueidentifier', 'char', 'varchar', 'text')
and TABLE_NAME NOT IN ('table_you_dont_want_to_look_in', 'and_another_one')
Print 'Searching...
'
declare #index int
declare #customsql nvarchar(2000)
WHILE EXISTS (SELECT * FROM #tmpSearch)
BEGIN
SELECT #index = min(ListIndex) FROM #tmpSearch
SELECT #customSQL = CustomSQL FROM #tmpSearch WHERE ListIndex = #index
IF #customSql IS NOT NULL
EXECUTE (#customSql)
SET NOCOUNT ON
DELETE #tmpSearch WHERE ListIndex = #index
SET NOCOUNT OFF
END
print 'the end.'
ROLLBACK