diff --git a/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js b/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js index 682cdeb48..3bdf57629 100644 --- a/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js +++ b/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js @@ -90,7 +90,7 @@ function getColumnInfo({ /** * @param {ReturnType} fieldType * @param {any} item - * @param {Array>} columns + * @param {Array<{ objectId: string; columnComment: string }>} columns * @returns {string|null} */ function createObjectContentHash(fieldType, item, columns) { @@ -273,8 +273,8 @@ class MsSqlAnalyser extends DatabaseAnalyser { async _getFastSnapshot() { const modificationsQueryData = await this.analyserQuery('modifications'); - const columnsRows = await this.analyserQuery('columns', ['tables']); - const columns = columnsRows.rows.map(getColumnInfo); + const baseColumnsRows = await this.analyserQuery('columns', ['tables']); + const baseColumns = baseColumnsRows.rows.map(getColumnInfo); const tableSizes = await this.analyserQuery('tableSizes'); const res = DatabaseAnalyser.createEmptyStructure(); @@ -285,7 +285,7 @@ class MsSqlAnalyser extends DatabaseAnalyser { res[field].push({ objectId, - contentHash: createObjectContentHash(field, item, columns), + contentHash: createObjectContentHash(field, item, baseColumns), schemaName, pureName, }); diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/baseColumns.js b/plugins/dbgate-plugin-mssql/src/backend/sql/baseColumns.js new file mode 100644 index 000000000..497d48b77 --- /dev/null +++ b/plugins/dbgate-plugin-mssql/src/backend/sql/baseColumns.js @@ -0,0 +1,10 @@ +module.exports = ` +select c.object_id as objectId, + ep.value as columnComment +from sys.columns c +inner join sys.objects o on c.object_id = o.object_id +INNER JOIN sys.schemas u ON u.schema_id=o.schema_id +left join sys.extended_properties ep on ep.major_id = c.object_id and ep.minor_id = c.column_id and ep.name = 'MS_Description' +where o.type IN ('U', 'V') and o.object_id =OBJECT_ID_CONDITION and u.name =SCHEMA_NAME_CONDITION +order by c.column_id +`; diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/index.js b/plugins/dbgate-plugin-mssql/src/backend/sql/index.js index 4125b1ebd..1676b4758 100644 --- a/plugins/dbgate-plugin-mssql/src/backend/sql/index.js +++ b/plugins/dbgate-plugin-mssql/src/backend/sql/index.js @@ -13,6 +13,7 @@ const viewColumns = require('./viewColumns'); const indexes = require('./indexes'); const indexcols = require('./indexcols'); const triggers = require('./triggers'); +const baseColumns = require('./baseColumns'); module.exports = { columns, @@ -30,4 +31,5 @@ module.exports = { indexcols, tableSizes, triggers, + baseColumns, }; diff --git a/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js index 66ddde21d..fd731ab64 100644 --- a/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js +++ b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js @@ -168,21 +168,34 @@ class MsSqlDumper extends SqlDumper { changeColumnComment(oldcol, newcol) { if (oldcol.columnComment === newcol.columnComment) return; - if (oldcol.columnComment) this.dropColumnComment(newcol); + if (oldcol.columnComment) this.dropColumnCommentIfExists(newcol); if (newcol.columnComment) this.createColumnComment(newcol); } /** * @param {import('dbgate-types').ColumnInfo} column */ - dropColumnComment(column) { + dropColumnCommentIfExists(column) { const { schemaName, columnName, pureName } = column; + const fullName = `${schemaName && schemaName + '.'}${pureName}`; + this.put('&>^if ^exists (&n'); + this.put('&>^select 1 ^from sys.extended_properties&n'); + this.put("^where major_id = OBJECT_ID('%s')&n", fullName); + this.put( + "^and minor_id = (^select column_id ^from sys.columns ^where object_id = OBJECT_ID('%s') ^and name = '%s')&n", + fullName, + columnName + ); + this.put("^and name = N'MS_Description'&<&<&n"); + this.put(')&n'); + this.put('&>^begin&n'); this.put('&>^exec sp_dropextendedproperty&n'); - this.put("@name = N'MS_Description',"); + this.put("@name = N'MS_Description',&n"); this.put("@level0type = N'SCHEMA', @level0name = '%s',&n", schemaName); this.put("@level1type = N'TABLE', @level1name = '%s',&n", pureName); - this.put("@level2type = N'COLUMN', @level2name = '%s'&<", columnName); + this.put("@level2type = N'COLUMN', @level2name = '%s'&<&n", columnName); + this.put('^end'); this.endCommand(); }