【问题标题】:Loop through each table in database and get first three digits of one column遍历数据库中的每个表并获取一列的前三位
【发布时间】:2019-02-12 20:27:22
【问题描述】:

我正在尝试创建一个表,该表将显示每个表名和 ID 列的前三个字符(每个表都有此列),然后将该数据放入表中。我们正在使用它来帮助映射 Salesforce 组织中的依赖关系,该依赖关系使用 dbAMP 复制到 SQL 上。我尽可能地修改了下面的代码,并正在寻求帮助来完成它。

更新:问题的前半部分已解决,现在运行代码以给出 ID 的前三个字符。我仍然可以使用帮助来转换此代码以将结果假脱机到一个表中。

USE Salesforce
GO




IF OBJECT_ID('tempdb..#tempResults') IS NOT NULL
DROP TABLE #tempResults

CREATE TABLE #tempResults
(
[Object_ID] VARCHAR(3)
--, [org] VARCHAR(100)
, [Table_Name] VARCHAR(100)
)

DECLARE cur CURSOR FOR
SELECT 
    'SELECT DISTINCT LEFT(' + QUOTENAME(c.COLUMN_NAME) + ',3) AS 
[Object_ID], '''
--+ QUOTENAME(TABLE_CATALOG) + ' as [Org], '
+ QUOTENAME(TABLE_NAME) + ''' as [Table_Name] FROM ' 
+ QUOTENAME(TABLE_CATALOG) + '.' + QUOTENAME(TABLE_SCHEMA) + '.'  + QUOTENAME(TABLE_NAME) 

FROM INFORMATION_SCHEMA.COLUMNS AS c
WHERE   
c.[DATA_TYPE] IN ('nchar','varchar', 'nvarchar') 
AND c.[CHARACTER_MAXIMUM_LENGTH] = 18
and c.TABLE_NAME not like '%upload%'
and c.TABLE_NAME not like '%Delta%'
and c.TABLE_NAME not like '%Update%'
and c.TABLE_NAME not like '%Previous%'
and C.COLUMN_NAME = 'ID'


DECLARE @cmd VARCHAR(MAX);
OPEN cur;

FETCH NEXT FROM cur INTO @cmd;
WHILE @@FETCH_STATUS = 0
BEGIN
    --PRINT @cmd
    INSERT INTO #tempResults
    EXEC(@cmd);
FETCH NEXT FROM cur INTO @cmd;
END

CLOSE cur;
DEALLOCATE cur;

SELECT * FROM #tempResults

我没有将列 ID 修剪为前 3 个字符,也没有输出到表格。我对游标不太熟悉,所以我会很感激任何帮助。谢谢,

【问题讨论】:

    标签: tsql salesforce dbamp


    【解决方案1】:

    你真的很亲密。您编写选择的方式实际上是修剪列名,然后将该 3 个字符的列名附加到字符串,而不是从 ID 列中的实际数据中获取前三个字符。

    尝试更新您的选择,使LEFTQUOTENAME(c.COLUMN_NAME) 括在字符串内,如下所示。这个小改动使您的脚本可以在我的 salesforce 安装中运行。

    SELECT 
        'SELECT DISTINCT LEFT(' + QUOTENAME(c.COLUMN_NAME) + ',3) AS ' 
        + QUOTENAME(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) + ' FROM ' 
        + QUOTENAME(TABLE_CATALOG) + '.' + QUOTENAME(TABLE_SCHEMA) + '.' 
        + QUOTENAME(TABLE_NAME)
    FROM INFORMATION_SCHEMA.COLUMNS AS c
    WHERE   
        c.[DATA_TYPE] IN ('nchar','varchar', 'nvarchar') 
        AND c.[CHARACTER_MAXIMUM_LENGTH] = 18
        and c.TABLE_NAME not like '%upload%'
        and c.TABLE_NAME not like '%Delta%'
        and c.TABLE_NAME not like '%UPdate%'
        and c.TABLE_NAME not like '%Previous%'
        and C.COLUMN_NAME = 'ID'
    

    更新回答第二部分:

    首先,您需要一个目标表 - 我使用了一个临时表,但这可以作为永久表正常工作。

    我已将代码调整为输出两列而不是一列:IDSubstring(您的 3 个字符的 ID 部分)和 SourceTable(这与您之前用作列名的信息完全相同)。这样我们就知道 ID 部分属于哪个表。

    然后,在光标内部,我们不只是执行,而是这样做:

    INSERT INTO #tempResults
    EXEC(@cmd);
    

    这将填充我们的表格并为我们提供可选值。

    CREATE TABLE #tempResults
    (
        [IDSubstring] VARCHAR(3)
        , [SourceTable] VARCHAR(50)
    )
    
    DECLARE cur CURSOR FOR
    SELECT 
        'SELECT DISTINCT LEFT(' + QUOTENAME(c.COLUMN_NAME) + ',3) AS [IDSubstring], '''
        + QUOTENAME(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) + ''' as [SourceTable] FROM ' 
        + QUOTENAME(TABLE_CATALOG) + '.' + QUOTENAME(TABLE_SCHEMA) + '.' 
        + QUOTENAME(TABLE_NAME)
    FROM INFORMATION_SCHEMA.COLUMNS AS c
    WHERE   
        c.[DATA_TYPE] IN ('nchar','varchar', 'nvarchar') 
        AND c.[CHARACTER_MAXIMUM_LENGTH] = 18
        and c.TABLE_NAME not like '%upload%'
        and c.TABLE_NAME not like '%Delta%'
        and c.TABLE_NAME not like '%UPdate%'
        and c.TABLE_NAME not like '%Previous%'
        and C.COLUMN_NAME = 'ID'
    
    
    DECLARE @cmd VARCHAR(MAX);
    OPEN cur;
    
    FETCH NEXT FROM cur INTO @cmd;
    WHILE @@FETCH_STATUS = 0
    BEGIN
        --PRINT @cmd
        INSERT INTO #tempResults
        EXEC(@cmd);
    FETCH NEXT FROM cur INTO @cmd;
    END
    
    CLOSE cur;
    DEALLOCATE cur;
    
    SELECT * FROM #tempResults
    

    更新 2

    您认为这是''' 的问题是正确的

    ''' 存在是因为我们需要在其中构建带有单引号的字符串。

    举例:

    SELECT '' 不返回任何内容 而SELECT '''' 返回 '

    SELECT 'This is an example''' 将返回这是一个例子'

    所以''' 是一个更大的字符串定义的一部分,它以“This”之前的初始 ' 开头,可以这样分解——前两个单引号是我们要在字符串中打印的单引号,而第三个单引号是字符串终止引号。如果您只是运行 select 语句并查看它的输出,您可以看到每个单引号被插入到字符串的哪个位置。

    更新的SELECT 如下。

    SELECT 
        'SELECT DISTINCT LEFT(' + QUOTENAME(c.COLUMN_NAME) + ',3) AS [Object_ID], '''
        + QUOTENAME(TABLE_CATALOG) + ''' as [Org], '''
        + QUOTENAME(TABLE_NAME) + ''' as [Table_Name] FROM ' 
        + QUOTENAME(TABLE_CATALOG) + '.' + QUOTENAME(TABLE_SCHEMA) + '.'  + QUOTENAME(TABLE_NAME) 
    FROM INFORMATION_SCHEMA.COLUMNS AS c
    WHERE   
    c.[DATA_TYPE] IN ('nchar','varchar', 'nvarchar') 
    AND c.[CHARACTER_MAXIMUM_LENGTH] = 18
    and c.TABLE_NAME not like '%upload%'
    and c.TABLE_NAME not like '%Delta%'
    and c.TABLE_NAME not like '%Update%'
    and c.TABLE_NAME not like '%Previous%'
    and C.COLUMN_NAME = 'ID'
    

    【讨论】:

    • 太棒了!谢谢!第一部分已经解决,第二部分仍然存在。我现在如何将这些结果“汇总”到表格中?
    • @MikeMarshall,对不起!我也更新了答案以涵盖第二部分。
    • 如此接近。这是我的更新代码。发布后我意识到我们还需要一个专栏,但是当我添加专栏时我无法让它正常运行。我相当确定'''(三个单引号)的位置。我不明白它们的功能。我已经在顶部发布了我(再次)更新的代码
    • 所以这个特殊的脚本位(几乎)与您在 VBA 中执行此操作的方式相同。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2015-04-19
    • 2013-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多