diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index 4b46f2ddf..2bc53e0d0 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -784,12 +784,17 @@ export class SqlDumper implements AlterProcessor { } } - declareVariable(name: string, type: string, defaultValueLiteral?: string) {} - executeCallable(func: CallableObjectInfo, argLiteralsByName: { [name: string]: string }) { - this.putCmd( - '^call %f(%,s)', + callableTemplate(func: CallableObjectInfo) { + this.put( + '^call %f(&>&n', func, - (func.parameters || []).map(x => argLiteralsByName[x.parameterName]) ); + + this.putCollection(',&n', func.parameters || [], param => { + this.putRaw(param.parameterMode == 'IN' ? ':' + param.parameterName : param.parameterName); + }); + + this.put('&<&n'); + this.endCommand(); } } diff --git a/packages/types/dumper.d.ts b/packages/types/dumper.d.ts index e6c2e3222..f6025cc5a 100644 --- a/packages/types/dumper.d.ts +++ b/packages/types/dumper.d.ts @@ -17,8 +17,7 @@ export interface SqlDumper extends AlterProcessor { createDatabase(name: string); dropDatabase(name: string); - declareVariable(name: string, type: string, defaultValueLiteral?: string); - executeCallable(func: CallableObjectInfo, argLiteralsByName: { [name: string]: string }); + callableTemplate(func: CallableObjectInfo); endCommand(); allowIdentityInsert(table: NamedObjectInfo, allow: boolean); diff --git a/packages/web/src/tabs/QueryTab.svelte b/packages/web/src/tabs/QueryTab.svelte index 350eaa492..731170c98 100644 --- a/packages/web/src/tabs/QueryTab.svelte +++ b/packages/web/src/tabs/QueryTab.svelte @@ -419,7 +419,7 @@ let queryParameterStyle = localStorage.getItem(`tabdata_queryParamStyle_${tabid}`) ?? initialArgs?.queryParameterStyle ?? - (initialArgs?.scriptTemplate == 'EXECUTE PROCEDURE' || initialArgs?.scriptTemplate == 'CALL FUNCTION' ? ':' : null); + (initialArgs?.scriptTemplate == 'CALL OBJECT' ? ':' : null); diff --git a/packages/web/src/utility/applyScriptTemplate.ts b/packages/web/src/utility/applyScriptTemplate.ts index ef4a98761..124e32f21 100644 --- a/packages/web/src/utility/applyScriptTemplate.ts +++ b/packages/web/src/utility/applyScriptTemplate.ts @@ -70,29 +70,15 @@ export default async function applyScriptTemplate( return createSql.replace(/^\s*create\s+/i, alterPrefix); } } - if (scriptTemplate == 'EXECUTE PROCEDURE' || scriptTemplate == 'CALL FUNCTION') { + if (scriptTemplate == 'CALL OBJECT') { const procedureInfo = dbinfo ? extractDbObjectInfo(dbinfo, props) : await getSqlObjectInfo(props); const connection = connectionInfo || (await getConnectionInfo(props)); const driver = findEngineDriver(connection, extensions) || driverBase; const dmp = driver.createDumper(); if (procedureInfo) { - const argLiteralsByName = {}; - for (const param of procedureInfo.parameters || []) { - const sqlVarName = param.parameterName?.startsWith('@') - ? param.parameterName?.substring(1) - : param.parameterName; - - dmp.declareVariable( - param.parameterName, - param.dataType, - param.parameterMode == 'OUT' ? null : `:${sqlVarName}` - ); - argLiteralsByName[param.parameterName] = param.parameterName; - } - dmp.executeCallable(procedureInfo, argLiteralsByName); + dmp.callableTemplate(procedureInfo); } - // if (procedureInfo) dmp.put('^execute %f', procedureInfo); return dmp.s; } @@ -161,7 +147,7 @@ export function getSupportedScriptTemplates(objectTypeField: string): { label: s }, { label: 'EXECUTE', - scriptTemplate: 'EXECUTE PROCEDURE', + scriptTemplate: 'CALL OBJECT', }, ]; @@ -177,7 +163,7 @@ export function getSupportedScriptTemplates(objectTypeField: string): { label: s }, { label: 'CALL', - scriptTemplate: 'CALL FUNCTION', + scriptTemplate: 'CALL OBJECT', }, ]; } diff --git a/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js index 9fbdea5ad..4cfdaf2eb 100644 --- a/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js +++ b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js @@ -161,26 +161,25 @@ class MsSqlDumper extends SqlDumper { this.put('^select ^scope_identity()'); } - declareVariable(name, type, defaultValueLiteral) { - this.put('^declare %s %s', name, type); - if (defaultValueLiteral) { - this.put(' = %s', defaultValueLiteral); - } - this.endCommand(); - } - - executeCallable(func, argLiteralsByName) { + callableTemplate(func) { const putParameters = (parameters, delimiter) => { - this.putCollection( - delimiter, - (parameters || []), param => { - this.putRaw(argLiteralsByName[param.parameterName]); - if (param?.parameterMode == 'OUT') this.put(' ^output'); + this.putCollection(delimiter, parameters || [], param => { + this.putRaw(param.parameterName); + if (param?.parameterMode == 'OUT') this.put(' ^output'); + }); + }; + const putDeclareParameters = parameters => { + for (const param of parameters || []) { + this.put('^declare %s %s', param.parameterName, param.dataType); + if (param.parameterMode == 'IN') { + this.put(' = :%s', param.parameterName.substring(1)); } - ); + this.endCommand(); + } }; if (func.objectTypeField == 'procedures') { + putDeclareParameters(func.parameters); this.put('^execute %f&>&n', func); putParameters(func.parameters, ',&n'); this.put('&<&n'); @@ -188,11 +187,10 @@ class MsSqlDumper extends SqlDumper { } if (func.objectTypeField == 'functions') { + const pars = (func.parameters || []).filter(x => x.parameterMode != 'OUT'); + putDeclareParameters(pars); this.put('^select %f(', func); - putParameters( - (func.parameters || []).filter(x => x.parameterMode != 'OUT'), - ', ' - ); + putParameters(pars, ', '); this.put(')'); this.endCommand(); }