Question: So I have a database with many tables that have a column that contains a GL Account value (for financial purposes). The column name varies by table (i.e. in one table the column is called "gldebitaccount" and in another table it's called "glcreditaccount"). I was able to find all combinations of table / column pairs using the following query:

```
SELECT c.name AS ColName, t.name AS TableName
FROM sys.columns c
    JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE '%gl%acc%'

```

This query returns close to 100 pairs of tables/columns. I am trying to find any value in any of those table/column pairs that exceeds 25 chars in length. For an individual table/column, I'd typically use:

```
SELECT *
FROM tableName
WHERE LEN(columnName)>25

```

I want to avoid having to run that query 100 times with each pair. Is there any way I can do a "for each" (which I know is frowned upon in SQL since everything should be set-based). I've done sub-SELECT statements before, but not any that involved change the table in the FROM clause. Any ideas or help would be greatly appreciated!

Thanks in advance!

Answer: 
Yet another solution with dynamic SQL.

But now without cursors. It uses FOR XML statement and should be much faster.

```
DECLARE @sqlstatement VARCHAR(MAX);

SET @sqlstatement =
    REPLACE (
        STUFF ( (
            SELECT 'UNION ALL SELECT ''' + t.name + ''' as TableName, '''
                + c.name + ''' AS ColumnName, '
                + c.name + ' AS Value FROM '
                + t.name + ' WHERE LEN (' + c.name + ') ' + CHAR(62) + ' 25'
            FROM sys.columns c
            INNER JOIN sys.tables t ON c.object_id = t.object_id
            WHERE c.name LIKE '%gl%acc%'
            FOR XML PATH('')
            ), 1, 10, '')
        , '&gt;', '>')

EXEC (@sqlstatement)

```

You may want to add extra filter for columns by their type and max\_length:

```
INNER JOIN sys.types ty ON c.system_type_id = ty.system_type_id
    AND (
        ty.name IN ('text', 'ntext')
        OR (
            ty.name IN ('varchar', 'char', 'nvarchar', 'nchar')
            AND (c.max_length > 25 OR c.max_length = -1)
    )

```
You will need to create dynamic SQL because you cannot dynamically specify the source table. You could do this using a cursor, or write a select statement that makes a row for each statement you need to run. This shows how to do it with a cursor. You problem looks like an acceptable usage for a cursor:

```
DECLARE @ColName VARCHAR(MAX);
DECLARE @TableName VARCHAR(MAX);
DECLARE @SomeSQL VARCHAR(MAX);

DECLARE db_cursor CURSOR FOR  
    SELECT c.name AS ColName, t.name AS TableName
    FROM sys.columns c
        JOIN sys.tables t ON c.object_id = t.object_id
    WHERE c.name LIKE '%gl%acc%'

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @ColName, @TableName;

WHILE @@FETCH_STATUS = 0  
BEGIN  

    -- you need to make dynamic SQL
    SELECT @SomeSQL = 'SELECT * FROM ' + @TableName + ' WHERE LEN(' + @ColName + ') > 25;'
    PRINT(@SomeSQL + CHAR(10));

    -- you could execute it directly if you wish.
    --EXEC (@SomeSQL);

    FETCH NEXT FROM db_cursor INTO @ColName, @TableName;

END  

CLOSE db_cursor;
DEALLOCATE db_cursor;

```