我使用SQL Server 2012的SQL Server查询选择某种类型的所有列,也表明
我查询的第一部分已经回答了这个thread其最大值。但是我也想要第二列显示相应表格中该列的相应最大值。
我试过这种方法:使用一个函数,它以表名和列名作为参数并返回最大值。但从函数使用动态SQL是非法的。此外,我似乎无法从一个SELECT查询中调用一个函数。
我也试过使用存储过程,但我无法弄清楚如何调用它并使用它。请建议替代方法来实现这一点。
我是SQL Server的新手。
感谢
我使用SQL Server 2012的SQL Server查询选择某种类型的所有列,也表明
我查询的第一部分已经回答了这个thread其最大值。但是我也想要第二列显示相应表格中该列的相应最大值。
我试过这种方法:使用一个函数,它以表名和列名作为参数并返回最大值。但从函数使用动态SQL是非法的。此外,我似乎无法从一个SELECT查询中调用一个函数。
我也试过使用存储过程,但我无法弄清楚如何调用它并使用它。请建议替代方法来实现这一点。
我是SQL Server的新手。
感谢
您可以使用下面的SP和提高它按您的需求,
CRETE PROCEDURE Getmaxtablecolval
AS
BEGIN
CREATE TABLE #t
(
tablename VARCHAR(50),
columnname VARCHAR(50),
id INT,
counts INT
)
INSERT INTO #t
SELECT table_name [Table Name],
column_name [Column Name],
NULL,
NULL
FROM information_schema.columns
WHERE data_type = 'INT'
BEGIN TRAN
DECLARE @id INT
SET @id = 0
UPDATE #t
SET @id = id = @id + 1
COMMIT TRAN
DECLARE @RowCount INT
SET @RowCount = (SELECT Count(0)
FROM #t)
DECLARE @I INT
SET @I = 1
DECLARE @Counter INT
DECLARE @TName VARCHAR(50)
DECLARE @CName VARCHAR(50)
DECLARE @DynamicSQL AS VARCHAR(500)
WHILE (@I <= @RowCount)
BEGIN
SELECT @TName = tablename
FROM #t
WHERE id = @I
SELECT @CName = columnname
FROM #t
WHERE id = @I
SET @DynamicSQL = 'Update #T Set Counts = '
+ '(Select ISNull(Max(' + @CName + '), 0) From '
+ @TName + ') Where Id = '
+ CONVERT(VARCHAR(10), @I)
--PRINT @DynamicSQL
EXEC (@DynamicSQL)
SET @I = @I + 1
END
SELECT *
FROM #t
END
go
Getmaxtablecolval
您可以创建一个过程出这一点:
CREATE PROCEDURE GET_COLUMNS_WITH_MAX_VALUE
@COLUMN_TYPE NVARCHAR(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- DUMMY VARIABLE TO COPY STRUCTURE TO TEMP
DECLARE @DUMMY TABLE
(
TABLE_NAME NVARCHAR(50),
COLUMN_NAME NVARCHAR(50),
MAX_VALUE NVARCHAR(MAX)
)
-- CREATE TEMP TABLE FOR DYNAMIC SQL
SELECT TOP 0 * INTO #TABLE FROM @DUMMY
INSERT INTO #TABLE
(TABLE_NAME, COLUMN_NAME)
SELECT TABLE_NAME, COLUMN_NAME
FROM information_schema.columns where data_type = @COLUMN_TYPE
DECLARE @TABLE_NAME VARCHAR(50) -- database name
DECLARE @COLUMN_NAME VARCHAR(256) -- path for backup files
DECLARE db_cursor CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME
FROM #TABLE
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @TABLE_NAME, @COLUMN_NAME
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL NVARCHAR(MAX) = 'UPDATE #TABLE SET MAX_VALUE = (SELECT MAX([' + @COLUMN_NAME + ']) FROM [' + @TABLE_NAME + ']) '
+ 'WHERE [COLUMN_NAME] = ''' + @COLUMN_NAME + ''' AND TABLE_NAME = ''' + @TABLE_NAME + '''';
PRINT @SQL
EXEC (@SQL)
FETCH NEXT FROM db_cursor INTO @TABLE_NAME, @COLUMN_NAME
END
CLOSE db_cursor
DEALLOCATE db_cursor
SELECT * FROM #TABLE
DROP TABLE #TABLE
END
GO
用法:
个结果:
TABLE1 ID 50
TABLE2 ID 100
TABLE3 CarID 20
TABLE4 StudentID 30
不错!与@Lucky类似的方法。但我喜欢你使用光标的事实。此外,它可以将数据类型作为参数传递给存储过程。 :)再一次,它可以一次完成,没有临时表吗? – MercuryX
@MercuryX根据单个查询中某一行的值构建动态查询是不可能的。必须将“SELECT MAX(ColumName)”编译为有效的列名称。它不能基于另一列的值。 – user3185569
是的,这是真的!我想我喜欢你的答案:) – MercuryX
我认为最简单的解决办法是存储过程。据我所知:
我另外,如果你写这样的程序:
编号重复和性能是没有问题的,看看下面的代码片段:
CREATE PROC FindMaxColumnValues
@type sysname = '%',
@table sysname = '%'
AS
DECLARE @result TABLE (TableName sysname, ColumnName sysname, MaxValue NVARCHAR(MAX))
DECLARE @tab sysname
DECLARE @col sysname
DECLARE cur CURSOR FOR
SELECT TABLE_NAME TableName, COLUMN_NAME [Column Name]
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE LIKE @type and TABLE_NAME LIKE @table
OPEN cur
FETCH NEXT FROM cur INTO @tab, @col
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @sql nvarchar(MAX) = 'SELECT '+QUOTENAME(@tab,'''')+' [TableName], '+QUOTENAME(@col, '''')+' [ColumnName], MAX('+QUOTENAME(@col)+') FROM '+QUOTENAME(@tab)
INSERT INTO @result EXEC(@sql)
FETCH NEXT FROM cur INTO @tab, @col
END
CLOSE cur
DEALLOCATE cur
SELECT * FROM @result
样品:
--MAX of INT's
EXEC FindMaxColumnValues 'INT'
--MAX of INT's in tables matching 'TestTab%'
EXEC FindMaxColumnValues 'INT', 'TestTab%'
--MAX of ALL columns
EXEC FindMaxColumnValues
结果:
TableName ColumnName MaxValue
IdNameTest ID 2
TestTable ID 5
TestTable Number 3
TableName ColumnName MaxValue
TestTable ID 5
TestTable Number 3
TableName ColumnName MaxValue
UpdateHistory UpdateTime 2016-07-14 12:21:37.00
IdNameTest ID 2
IdNameTest Name T2
TestTable ID 5
TestTable Name F
TestTable Number 3
Dyl你在“另外”部分提到的3点是非常有帮助的。我拥有的数据库确实具有**相同的表名和列名,但使用不同的模式**。有很多条目,所以我很担心使用MAX。注射始终是一个问题,但我的设置中的所有术语都没有空间或其他特殊字符。 – MercuryX
好的!所以你正在使用临时表!这是一个不错的方法!但是,您首先使用列名和表名创建表,然后运行循环来填充最大值。有办法**一次去做**吗?或没有临时表? – MercuryX
嗯,我们需要一个(temp)表来创建一个动态查询,因为结果不属于一个table.Since,因为我们需要循环直通,我们不能一次性创建它**。随意删除一条消息,以便进一步查询。 – Lucky