Click here to Skip to main content
15,894,825 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I found a public code that takes the tables and displays them along with the amount of records(rows). I used that code and tried to add more to it to allow more fields to be populated from each table. The problem is I cannot get just a general column name to use it keeps asking me specifically which table do I want to pull from. I want to take a general column which is the year of birth from all tables and populate the Listview as year 1 being the min year and year 2 being the max year of dates within those tables. I also want to be able to use the sys.database in the listview table to show which database the table is associated with when they view all tables at once.

so for listview as of now, I am able to see the table names and the max amount of records. this is how it should look:

| table name | records | Year1 | Year2| Database|


this code is not complete as I am having a hard time getting to the individual column names and also using sys.database here is the code I am working on:

SELECT 
    [TableName] = so.name, 
    [RowCount] = MAX(si.rows), 
	[databases] = SCH
	[Minimum] = MIN(CMI.),
	[Maximum] = MAX(CMA.number)
	FROM 
    sysobjects so, 
    sysindexes si, 
	sys.databases SCM,
	sys.all_columns CMI,
	syscolumns CMA
WHERE 
    so.xtype = 'U' 
    AND 
    si.id = OBJECT_ID(so.name)
	and
	CMA.
	and
	CMI.
	and 
	SCM
GROUP BY 
    so.name 
ORDER BY 
    5 DESC


I have placed in a portion of what I believe to be in the right direction of what I am trying to accomplish.

I want to be able to get the min and max of a particular column and I want to also display which database these tables belong to. in the end I am hoping to show all my databases combined information as listed above.

here is the original:

SELECT 
    [TableName] = so.name, 
    [RowCount] = MAX(si.rows) 
FROM 
    sysobjects so, 
    sysindexes si 
WHERE 
    so.xtype = 'U' 
    AND 
    si.id = OBJECT_ID(so.name) 
GROUP BY 
    so.name 
ORDER BY 
    2 DESC


anyways I am trying to get this with a few extra fields, I will be passing the values through a listview as an sqldatareader, which will make it an only read only view. I can use the original and it works fine as it only shows the actual table name and the max row count.

What I have tried:

I have tried to switch the properties from sys.columns to all columns and I have tried to set just the name itself CMA.name, CMI.name, and SCM.name

https://gyazo.com/f53f611cc9a9f6f2fd28c01de0e78ec9

I have inclded a picture
Posted
Updated 30-Jan-17 6:36am
v5
Comments
OriginalGriff 29-Jan-17 4:58am    
Sorry, but that is not a good question - it isn't even close to valid SQL. And your description doesn't help at all - I have no idea from the description and code what you are trying to accomplish.
So take a step back and try to explain what output you want with examples and remembering that we can't see your screen, access your HDD, or read your mind.
Use the "Improve question" widget to edit your question and provide better information.
Member 11856456 30-Jan-17 8:59am    
I have added additional information to the question and the format on how it should look.
CHill60 30-Jan-17 8:11am    
OriginalGriff will not realise that you have attempted to reply as you did not use the "Reply" link next to his post. However, the hyperlink doesn't actually work. The picture doesn't actually help to explain your problem either. It is really difficult to determine what your problem is
Member 11856456 30-Jan-17 9:00am    
Thank you, I did not realize that I didn't reply directly to the question he presented. I have added additional information, so hopefully that will help clarify what I am looking for.
CHill60 30-Jan-17 9:08am    
What are Year1 and Year2?

1 solution

Ok. I still think your set up is strange and we're struggling to understand what you are trying to do, however here is some stuff you can alter to your own requirements.

I'm creating a interim results table:
SQL
if exists (select * from INFORMATION_SCHEMA.TABLES 
where TABLE_NAME = 'tempResults' AND TABLE_SCHEMA = 'dbo') drop table dbo.tempResults

create table tempResults
(
	id int identity(1,1),
	databasename varchar(128),
	schemaname varchar(128),
	tablename varchar(128),
	columnname varchar(1128),
	rowsintable int,
	system_type_id int,
	minvalue varchar(128),
	maxvalue varchar(128)
)
Note the minvalue and maxvalue columns cannot be determined from the system tables (which is part of the problem with your approach)

I've populated that table initially with every column of every table of every database on my server :
SQL
DECLARE @src NVARCHAR(MAX), @sql NVARCHAR(MAX);

SELECT @sql = N'', @src = N' UNION ALL 
SELECT ''$d'' as databasename, 
    s.name COLLATE SQL_Latin1_General_CP1_CI_AI as schemaname,
    t.name COLLATE SQL_Latin1_General_CP1_CI_AI as tablename,
	c.name COLLATE SQL_Latin1_General_CP1_CI_AI as columnname,
	i.rowcnt as rowsintable, c.system_type_id as system_type_id,
	cast(0 as varchar(128)) as minvalue, cast(0 as varchar(128)) as maxvalue
  FROM [$d].sys.schemas AS s
  INNER JOIN [$d].sys.tables AS t
  ON s.[schema_id] = t.[schema_id]
  INNER JOIN [$d].sys.all_columns as c ON c.object_id=t.object_id
  INNER JOIN [$d].sys.sysindexes i ON c.object_id = i.id
';

SELECT @sql = @sql + REPLACE(@src, '$d', name)
  FROM sys.databases
  WHERE database_id > 4
    AND [state] = 0
    AND HAS_DBACCESS(name) = 1;

SET @sql = STUFF(@sql, 1, 10, CHAR(13) + CHAR(10));
SET @sql = 'INSERT INTO tempresults SELECT * FROM (' + @sql + ') AS C '
--PRINT @sql;
EXEC sys.sp_executesql @sql;
You might prefer to (i.e. should) limit this to the table naming convention that you are using for your user tables OR the column name(s) that contain the data you want.

I then update this table by querying the actual tables on the databases themselves:
SQL
declare @dbname varchar(max)
declare @scheme varchar(max)
declare @table varchar(max)
declare @column varchar(max)
declare @ccSql nvarchar(max)
declare @maxid int =(SELECT MAX(id) from tempresults)
declare @curid int = (SELECT MIN(id) from tempresults)

WHILE @curid <= @maxid
BEGIN
	SELECT @dbname = databasename, 
		@scheme = schemaname, 
		@table  = tablename, 
		@column = columnname 
	FROM tempresults TD 
	INNER JOIN sys.types T on TD.system_type_id = T.system_type_id
	WHERE id = @curid
	AND T.name NOT IN ('bit','image','text','ntext') -- and any others that can't be passed to MIN/MAX

	if @column IS NOT NULL 
	BEGIN
		SET @ccSql = 'UPDATE tempresults SET minvalue = B.the_min, maxvalue=B.the_max FROM ('
		SET @ccSql = @ccSql + 'SELECT MIN(['+@column+']) AS the_min, MAX([' + @column + ']) AS the_max FROM ['
		SET @ccSql = @ccSql + @dbname + '].[' + @scheme + '].[' +@table +']) B WHERE id=' + cast(@curid as varchar(128))

		--PRINT @ccSql
		EXEC sys.sp_executesql @ccsql;
	
	END
	SET @curid = @curid + 1

END
Points to consider:
1. You shouldn't need to be doing this - there is clearly something wrong with your design.
2. This takes a long time to run, so try to filter it further
3. You might like to limit the columns examined even further to just include date or datetime or integers (I have no idea where you are getting Year1 and Year2 from) - this would improve the performance of the query.
4. You may or may not get some warnings about NULL values in aggregate functions (I ignored these).

I get results similar to the following:
Northwind dbo Employees	EmployeeID	9	56	1	9
Northwind dbo Employees	LastName	9	231	Buchanan	Suyama
Northwind dbo Employees	FirstName	9	231	Andrew	Steven
Northwind dbo Employees	TitleOfCourtesy	9	231	Dr.	Ms.
Northwind dbo Employees	BirthDate	9	61	Sep 19 1937 12:00AM	Jan 27 1966 12:00AM
Northwind dbo Employees	HireDate	9	61	Apr  1 1992 12:00AM	Nov 15 1994 12:00AM
Northwind dbo Employees	Address	9	231	14 Garrett Hill	Edgeham Hollow
Winchester Way
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900