1

我做了一个复杂更新的简单示例,但作为 Oracle 开发人员,我很惊讶这确实有效,因为我没有加入获取更新值的选择,仅在 WHERE EXISTS 部分。

所以我的问题是这是如何工作的?当它没有加入时,它如何真正更新正确的记录?

UPDATE dbo.gg_ddl_changes_mssql
SET gg_ddl_changes_mssql.column_id       = a.ordinal_position, 
    gg_ddl_changes_mssql.default_value   = a.default_value, 
    gg_ddl_changes_mssql.nullable        = a.is_nullable, 
    gg_ddl_changes_mssql.data_type       = a.data_type, 
    gg_ddl_changes_mssql.data_length     = a.character_maximum_length, 
    gg_ddl_changes_mssql.data_precision  = a.numeric_precision,
    gg_ddl_changes_mssql.data_scale      = a.numeric_scale, 
    gg_ddl_changes_mssql.date_precision  = a.datetime_precision, 
    gg_ddl_changes_mssql.pk_id           = a.pk_id, 
    gg_ddl_changes_mssql.pk_name         = a.CONSTRAINT_NAME, 
    gg_ddl_changes_mssql.last_updated    = GETDATE()
FROM (SELECT c.ordinal_position, 
             LEFT(c.column_default, 2000) as "default_value", 
             c.is_nullable, c.data_type, 
             c.character_maximum_length, 
             c.numeric_precision, 
             c.numeric_scale, 
             c.datetime_precision, 
             pc.ordinal_position as "pk_id", 
             pc.constraint_name
   from INFORMATION_SCHEMA.tables  AS t, 
        INFORMATION_SCHEMA.COLUMNS AS c
LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS p
  ON c.table_name = p.table_name
LEFT OUTER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE pc
  ON (p.constraint_name = pc.constraint_name
  AND c.column_name     = pc.column_name)
 WHERE t.table_type       = 'BASE TABLE' 
   AND t.table_name       = c.table_name 
   AND t.table_schema     = c.table_schema 
   AND p.constraint_type  = 'PRIMARY KEY'
   ) as a
WHERE EXISTS (SELECT *
                FROM INFORMATION_SCHEMA.tables  AS t1, 
                     INFORMATION_SCHEMA.COLUMNS AS c1
              LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS p1
                ON c1.table_name = p1.table_name
              LEFT OUTER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE pc1
                ON (p1.constraint_name = pc1.constraint_name
                AND c1.column_name     = pc1.column_name)
               WHERE t1.table_type       = 'BASE TABLE' 
                 AND c1.table_schema     = gg_ddl_changes_mssql.table_schema
                 AND c1.table_name       = gg_ddl_changes_mssql.table_name
                 AND c1.column_name      = gg_ddl_changes_mssql.column_name
                 AND t1.table_name       = c1.table_name 
                 AND t1.table_schema     = c1.table_schema 
                 AND p1.constraint_type  = 'PRIMARY KEY'
                 AND ( c1.ordinal_position             != gg_ddl_changes_mssql.column_id
                   OR  LEFT(c1.column_default, 2000)   != gg_ddl_changes_mssql.default_value
                   OR  c1.is_nullable                  != gg_ddl_changes_mssql.nullable
                   OR  c1.data_type                    != gg_ddl_changes_mssql.data_type
                   OR  c1.character_maximum_length     != gg_ddl_changes_mssql.data_length
                   OR  c1.numeric_precision            != gg_ddl_changes_mssql.data_precision 
                   OR  c1.numeric_scale                != gg_ddl_changes_mssql.data_scale
                   OR  c1.datetime_precision           != gg_ddl_changes_mssql.date_precision
                   or  pc1.ordinal_position            != gg_ddl_changes_mssql.pk_id
                   or  pc1.constraint_name             != gg_ddl_changes_mssql.pk_name))

在 Oracle 中,我们将获得一个值,因为如果 tableY 中有多个记录,则选择值将返回许多值。

4

2 回答 2

1

试试这个——

UPDATE x
SET x.column1 = y.column1
FROM dbo.tableX x
JOIN dbo.tableY y ON x.primary_key_col = y.primary_key_col
WHERE x.column1 != y.column1

更新:

UPDATE t
SET column_id       = c.ordinal_position, 
    default_value   = LEFT(c.column_default, 2000), 
    nullable        = c.is_nullable, 
    data_type       = c.data_type, 
    data_length     = c.character_maximum_length, 
    data_precision  = c.numeric_precision,
    data_scale      = c.numeric_scale, 
    date_precision  = c.datetime_precision, 
    pk_id           = pc.ordinal_position, 
    pk_name         = pc.constraint_name, 
    last_updated    = GETDATE()
FROM dbo.gg_ddl_changes_mssql t
JOIN INFORMATION_SCHEMA.TABLES ta ON ta.table_schema = t.table_schema 
                                 AND ta.table_name = t.table_name
                                 AND ta.TABLE_TYPE = 'BASE TABLE'
JOIN INFORMATION_SCHEMA.COLUMNS c ON ta.table_name = c.table_name 
                                 AND ta.table_schema = c.table_schema
                                 AND c.column_name = t.column_name
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS p ON c.table_name = p.table_name 
                                                AND p.constraint_type = 'PRIMARY KEY'
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE pc ON p.constraint_name = pc.constraint_name 
                                                AND c.column_name = pc.column_name
WHERE 
         c.ordinal_position             != t.column_id
     OR  LEFT(c.column_default, 2000)   != t.default_value
     OR  c.is_nullable                  != t.nullable
     OR  c.data_type                    != t.data_type
     OR  c.character_maximum_length     != t.data_length
     OR  c.numeric_precision            != t.data_precision 
     OR  c.numeric_scale                != t.data_scale
     OR  c.datetime_precision           != t.date_precision
     OR  ISNULL(pc.ordinal_position, -1)!= t.pk_id
     OR  ISNULL(pc.constraint_name, '') != t.pk_name
于 2013-07-23T09:18:51.900 回答
1

您不必要地进行复杂查询

UPDATE X
SET X.column1 = Y.column1
FROM tableX X
INNER JOIN tableY Y
ON X.primary_key_col = Y.primary_key_col
WHERE X.column1 != Y.column1
于 2013-07-23T09:10:10.907 回答