Reputation: 27021
I have a table which contains a column named WhereClause
DECLARE @UserGroups TABLE (WhereClause nvarchar(1000), totalCount int)
The table has been populated with some values for WhereClause
but none for totalCount
column.
An example of the WhereClause
is "FirstName is null".
Basically for each row in the table, I'd need to calculate the COUNT(*) from another table (Users) and set the totalCount
on the above table.
The below doesn't work:
SELECT UG.WhereClause, U.TotalCount
FROM @UserGroups as UG
OUTER APPLY (SELECT COUNT(*) as 'TotalCount' FROM [Users] WHERE UG.WhereClause)
) U
I tried creating a sql function and calling exec sp_executesql within the function but it's not supported.
CREATE FUNCTION [dbo].[fn_UserGroupCount]
(
@whereClause as NVARCHAR(1000)
)
RETURNS @returnValue TABLE (TotalCount INT)
AS
BEGIN
DECLARE @stmt nvarchar(1500)
SET @stmt = 'SELECT COUNT(*) FROM [dbo].[Users]
WHERE ' + @whereClause
Exec sp_executesql @stmt
RETURN
END
SELECT * FROM [dbo].[fn_UserGroupCount]('Subject is null')
How would that be possible to populate my @UserGroups
table as mentioned?
Thanks
Upvotes: 0
Views: 19586
Reputation: 7763
I would use a cursor to build a string containing your update statements with the select count(*) from @whereclause built in. You can then execute this to perform your updates. See the SQLFiddle below:
UPDATED Now works where the where clause has single quotes in it and also apostrophes in where clauses
MS SQL Server 2008 Schema Setup:
create table users
(
userid int primary key identity,
name varchar(50),
subject varchar(50) null
);
INSERT INTO users (name, subject)
VALUES
('Fred', 'Maths'),
('Bill', null),
('Helen', 'English'),
('O''Keefe', 'Maths');
Query 1:
DECLARE @WhereClause nvarchar(1000)
DECLARE @stmt nvarchar(1500) = ''
CREATE TABLE #UserGroups (WhereClause nvarchar(1000), totalCount int)
INSERT #UserGroups VALUES ('Subject IS NULL', NULL)
INSERT #UserGroups VALUES ('Subject IS NOT NULL', NULL)
INSERT #UserGroups VALUES ('Subject =''Maths''', NULL)
INSERT #UserGroups VALUES ('name =''O''''Keefe''', NULL)
DECLARE cur CURSOR FOR
SELECT WhereClause FROM #UserGroups
OPEN cur
FETCH cur INTO @WhereClause
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @stmt = @stmt +
'UPDATE #UserGroups ' +
'SET totalCount = ' +
'(SELECT COUNT(*) FROM users WHERE ' + @WhereClause + ') ' +
'WHERE WhereClause = ''' + REPLACE(@WhereClause, '''', '''''') + ''';'
FETCH cur INTO @WhereClause
END
CLOSE cur
DEALLOCATE cur
--select @stmt
exec(@stmt)
SELECT *
FROM #UserGroups
DROP TABLE #UserGroups
| WHERECLAUSE | TOTALCOUNT |
------------------------------------
| Subject IS NULL | 1 |
| Subject IS NOT NULL | 3 |
| Subject ='Maths' | 2 |
| name ='O''Keefe' | 1 |
Upvotes: 0
Reputation: 8832
Try this, you'll have to use temporary table for dynamic SQL to be able to reach it (@UserGroups
won't work so I replaced it with #UserGroups
):
CREATE TABLE #UserGroups (WhereClause nvarchar(1000), totalCount int)
INSERT #UserGroups VALUES ('FirstName IS NULL', NULL)
INSERT #UserGroups VALUES ('FirstName IS NOT NULL', NULL)
DECLARE @sql VARCHAR(8000) = STUFF(
(
SELECT ';UPDATE #UserGroups SET totalCount = (SELECT COUNT(*) FROM [Users] WHERE ' + WhereClause + ') WHERE WhereClause = ''' + WhereClause + ''''
FROM #UserGroups
FOR XML PATH('')
), 1, 1, '')
PRINT @sql
EXEC(@sql)
SELECT *
FROM #UserGroups
DROP TABLE #UserGroups
However, problems might arise if WhereClause
contains quotes, something like FirstName LIKE 'Joe'
.
Upvotes: 4