diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index 589f877f5..4b46f2ddf 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -785,7 +785,11 @@ export class SqlDumper implements AlterProcessor { } declareVariable(name: string, type: string, defaultValueLiteral?: string) {} - executeCallable(func: CallableObjectInfo, argLiterals: string[]) { - this.putCmd('^call %f(%,s)', func, argLiterals); + executeCallable(func: CallableObjectInfo, argLiteralsByName: { [name: string]: string }) { + this.putCmd( + '^call %f(%,s)', + func, + (func.parameters || []).map(x => argLiteralsByName[x.parameterName]) + ); } } diff --git a/packages/types/dumper.d.ts b/packages/types/dumper.d.ts index 12c1ce669..e6c2e3222 100644 --- a/packages/types/dumper.d.ts +++ b/packages/types/dumper.d.ts @@ -18,7 +18,7 @@ export interface SqlDumper extends AlterProcessor { dropDatabase(name: string); declareVariable(name: string, type: string, defaultValueLiteral?: string); - executeCallable(func: CallableObjectInfo, argLiterals: string[]); + executeCallable(func: CallableObjectInfo, argLiteralsByName: { [name: string]: string }); endCommand(); allowIdentityInsert(table: NamedObjectInfo, allow: boolean); diff --git a/packages/web/src/utility/applyScriptTemplate.ts b/packages/web/src/utility/applyScriptTemplate.ts index f4ed28b0b..ef4a98761 100644 --- a/packages/web/src/utility/applyScriptTemplate.ts +++ b/packages/web/src/utility/applyScriptTemplate.ts @@ -77,7 +77,7 @@ export default async function applyScriptTemplate( const driver = findEngineDriver(connection, extensions) || driverBase; const dmp = driver.createDumper(); if (procedureInfo) { - const sqlVars = []; + const argLiteralsByName = {}; for (const param of procedureInfo.parameters || []) { const sqlVarName = param.parameterName?.startsWith('@') ? param.parameterName?.substring(1) @@ -88,9 +88,9 @@ export default async function applyScriptTemplate( param.dataType, param.parameterMode == 'OUT' ? null : `:${sqlVarName}` ); - sqlVars.push(param.parameterName); + argLiteralsByName[param.parameterName] = param.parameterName; } - dmp.executeCallable(procedureInfo, sqlVars); + dmp.executeCallable(procedureInfo, argLiteralsByName); } // if (procedureInfo) dmp.put('^execute %f', procedureInfo); return dmp.s; diff --git a/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js index f15994468..7f5ddabdd 100644 --- a/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js +++ b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js @@ -1,5 +1,4 @@ const { SqlDumper, testEqualColumns, arrayToHexString } = global.DBGATE_PACKAGES['dbgate-tools']; -const _zip = require('lodash/zip'); class MsSqlDumper extends SqlDumper { constructor(driver, options) { @@ -170,18 +169,33 @@ class MsSqlDumper extends SqlDumper { this.endCommand(); } - executeCallable(func, argLiterals) { - console.log('executeCallable', func, argLiterals); - if (func.objectTypeField == 'procedures') { - this.put('^execute %f&>&n', func, argLiterals); + executeCallable(func, argLiteralsByName) { + const putParameters = (parameters, delimiter) => { + this.putCollection( + delimiter, + (parameters || []), param => { + this.putRaw(argLiteralsByName[param]); + if (param?.parameterMode == 'OUT') this.put(' ^output'); + } + ); + }; - this.putCollection(',&n', _zip(func.parameters || [], argLiterals || []), ([param, value]) => { - this.putRaw(value); - if (param?.parameterMode == 'OUT') this.put(' ^output'); - }); + if (func.objectTypeField == 'procedures') { + this.put('^execute %f&>&n', func); + putParameters(func.parameters, ',&n'); this.put('&<&n'); this.endCommand(); } + + if (func.objectTypeField == 'functions') { + this.put('^select %f(', func); + putParameters( + (func.parameters || []).filter(x => x.parameterMode != 'OUT'), + ', ' + ); + this.put(')'); + this.endCommand(); + } } }