问题
I have this user-defined function:
CREATE FUNCTION [dbo].[COUNT_ROWS_TABLE]()
RETURNS TINYINT
AS
BEGIN
DECLARE @ROW_COUNT TINYINT
SELECT @ROW_COUNT = COUNT(*) FROM EMPLOYEE
RETURN @ROW_COUNT
END
GO
The problem is it only works for the table [dbo].[EMPLOYEE] and I don't want to Copy-Paste this function for every table on my database.
My attempt so far:
CREATE FUNCTION [dbo].[COUNT_ROWS_TABLE](@TABLE_NAME VARCHAR(50))
RETURNS TINYINT
AS
BEGIN
DECLARE @SQL_COMMAND NVARCHAR(100)
DECLARE @PARAM NVARCHAR(50)
DECLARE @ROW_COUNT TINYINT
SET @SQL_COMMAND = N'SELECT @RESULT = COUNT(*) FROM ' + @TABLE_NAME
SET @PARAM = N'@RESULT TINYINT OUTPUT'
EXEC SP_EXECUTESQL @SQL_COMMAND, @PARAM, @RESULT = @ROW_COUNT OUTPUT
RETURN @ROW_COUNT
END
GO
That code does not work because it doesn't allow those statements inside a function.
It works inside a stored procedure, though, but only if I PRINT the variable rather than RETURN it.
I need it to be a function, since I need to call it on an IF statement.
Any thoughts on how to achieve this? Thank you.
回答1:
You can use like below
ALTER FUNCTION [dbo].[COUNT_ROWS_TABLE](@TABLE_NAME VARCHAR(50))
RETURNS TINYINT
AS
BEGIN
DECLARE @ROW_COUNT TINYINT
SELECT @ROW_COUNT = SUM(b.rows)
FROM SYS.TABLES a INNER JOIN sys.partitions b ON b.OBJECT_ID = a.OBJECT_ID
WHERE a.is_ms_shipped = 0 AND b.index_id IN (1,0)
and a.name=@TABLE_NAME
GROUP BY a.name
RETURN @ROW_COUNT
END
GO
回答2:
For this kind of Query where you pass an object name as a parameter, you will need to use Dynamic Sql, but since you are only returning total number of rows this is achievable using sys schema cataloge views with use of Dynamic sql, you cannot use Dynamic Sql inside a UDF definition.
A Stored Procedure with an OUTPUT parameter
Here is what you would need to do.....
CREATE PROCEDURE [dbo].[COUNT_ROWS_TABLE]
@TABLE_NAME SYSNAME,
@Count INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = N'SELECT @Count = COUNT(*) FROM ' + QUOTENAME(@TABLE_NAME)
EXECUTE sp_executesql @Sql
, N'@Count INT OUTPUT'
, @Count OUTPUT
END
GO
Function using with sys schema
CREATE FUNCTION [dbo].[COUNT_ROWS_TABLE]
(
@TableName SYSNAME
)
RETURNS INT
AS
BEGIN
DECLARE @Row_Count INT;
SELECT @Row_Count = i.rowcnt
FROM sysindexes AS i
INNER JOIN sysobjects AS o ON i.id = o.id
WHERE i.indid < 2 AND OBJECTPROPERTY(o.id, 'IsMSShipped') = 0
AND o.NAME = @TableName
RETURN @Row_Count;
END
来源:https://stackoverflow.com/questions/25793020/create-a-function-for-counting-rows-from-any-table