遍历数据库中的每个表并获得一列的前三位数字

时间:2019-02-12 20:27:23

标签: tsql salesforce dbamp

我正在尝试创建一个表,该表将向我显示每个表名以及ID列的前三个字符(每个表都有此列),然后将数据放入表中。我们正在使用它来帮助映射Salesforce Org中的依赖关系,该依赖关系已使用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个字符,也没有输出到表中。我对光标不是很熟悉,所以希望能对您有所帮助。谢谢,

1 个答案:

答案 0 :(得分:1)

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

尝试更新您的选择,使LEFT括在字符串内的QUOTENAME(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'