001package gudusoft.gsqlparser.stmt.mssql; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.compiler.TSymbolTableManager; 005import gudusoft.gsqlparser.compiler.TVariable; 006import gudusoft.gsqlparser.nodes.*; 007import gudusoft.gsqlparser.nodes.mssql.TExecuteOption; 008import gudusoft.gsqlparser.stmt.TCreateFunctionStmt; 009import gudusoft.gsqlparser.stmt.TCreateProcedureStmt; 010import gudusoft.gsqlparser.stmt.TRoutine; 011import gudusoft.gsqlparser.stmt.TStoredProcedureSqlStatement; 012 013/** 014 * Execute a stored procedure or function, 015 * or Execute a character string 016 */ 017public class TMssqlExecute extends TCustomSqlStatement { 018 public TMssqlExecute (EDbVendor dbvendor){ 019 super(dbvendor); 020 sqlstatementtype = ESqlStatementType.sstmssqlexec ; 021 } 022 023 void buildsql() { 024 } 025 026 void clear() { 027 } 028 029 String getasprettytext() { 030 return ""; 031 } 032 033 void iterate(TVisitorAbs pvisitor) { 034 } 035 036 037 private String sqlText = null; 038 039 private TObjectName moduleName = null; 040 private TObjectName returnStatus = null; 041 private TExecParameterList parameters = null; 042 043 public String getSqlText() { 044 return sqlText; 045 } 046 047 public TObjectName getModuleName() { 048 return moduleName; 049 } 050 051 public TExecParameterList getParameters() { 052 return parameters; 053 } 054 055 public TObjectName getReturnStatus() { 056 return returnStatus; 057 } 058 059 public TExpressionList getStringValues() { 060 return stringValues; 061 } 062 063 public int getExecType() { 064 return execType; 065 } 066 067 private TExpressionList stringValues = null; 068 private int execType = TBaseType.metExecSp; 069 070 public TExpression getPreparedValue() { 071 return preparedValue; 072 } 073 074 private TExpression preparedValue;//couchbase 075 076 private boolean isValidProcedureCall(TSourceTokenList stList,TSyntaxError err){ 077 boolean ret = false; 078 079 if (stList.size() <= 1) return false; 080 TSourceToken st = stList.get(0); 081 if (st.tokencode == TBaseType.rrw_drop){ 082 TSourceToken nextst = stList.nextsolidtoken(st,1,false); 083 err.hint = "Unknown object type in drop statement"; 084 if (nextst != null){ 085 err.tokentext = nextst.toString(); 086 err.lineNo = nextst.lineNo; 087 err.columnNo = nextst.columnNo; 088 } 089 090 return false; 091 } 092 if (stList.get(1).tokentype == ETokenType.ttperiod) return true; 093 if (st.toString().toLowerCase().startsWith("sp")) return true; 094 if (st.toString().toLowerCase().startsWith("select")) return false; 095 if (st.toString().toLowerCase().startsWith("del")) return false; 096 if (st.toString().toLowerCase().startsWith("update")) return false; 097 if (st.toString().toLowerCase().startsWith("insert")) return false; 098 if (st.toString().toLowerCase().startsWith("create")) return false; 099 100 return ret; 101 } 102 private TExecuteOption executeOption; 103 104 public TExecuteOption getExecuteOption() { 105 return executeOption; 106 } 107 108 public EExecType getExecuteType() { 109 return executeType; 110 } 111 112 private EExecType executeType = EExecType.unknown; 113 114 private TObjectName intoVariable; 115 private TExpressionList usingVariables; 116 117 public TObjectName getIntoVariable() { 118 return intoVariable; 119 } 120 121 public TExpressionList getUsingVariables() { 122 return usingVariables; 123 } 124 125 public int doParseStatement(TCustomSqlStatement psql) { 126 if (rootNode == null) return -1; 127 if (!(rootNode instanceof TExecuteSqlNode)){ 128 if (this.sourcetokenlist.size() > 0){ 129 TSourceToken st1 = this.sourcetokenlist.get(0); 130 TSyntaxError err = new TSyntaxError(st1.toString(),st1.lineNo,st1.columnNo,"syntax error",EErrorType.sperror 131 ,TBaseType.MSG_ERROR_SYNTAX_ERROR 132 ,this,st1.posinlist); 133 if (!isValidProcedureCall(this.sourcetokenlist,err)) 134 this.parseerrormessagehandle(err); 135 } 136 return -1; 137 } 138 TExecuteSqlNode node = (TExecuteSqlNode)rootNode; 139 this.execType = node.getExecType(); 140 this.executeType = node.getExecuteType(); 141 this.preparedValue = node.getPreparedValue(); 142 this.intoVariable = node.getIntoVariable(); 143 this.usingVariables = node.getUsingVariables(); 144 145 this.executeOption = node.getExecuteOption(); 146 super.doParseStatement(psql); 147 148 149 if ((node.getExecType() == TBaseType.metExecSp)){ 150 this.moduleName = node.getModuleName(); 151 this.parameters = node.getParameters(); 152 this.returnStatus = node.getReturnStatus(); 153 this.linkServerName = node.getLinkServerName(); 154 if ((this.moduleName != null)&&(this.moduleName.toString().equalsIgnoreCase("sp_executesql"))){ 155 TExecParameter parameter = this.parameters.getExecParameter(0); 156 if (parameter.getParameterValue().getExpressionType() == EExpressionType.simple_object_name_t){ 157 TObjectName var = parameter.getParameterValue().getObjectOperand(); 158 if (var.getDbObjectType() == EDbObjectType.variable){ 159 TVariable symbolVariable = TSymbolTableManager.searchSymbolVariable(this.getFrameStack(),var.toString()); 160 if (symbolVariable != null){ 161 this.sqlText = symbolVariable.getVariableStr(); 162 //System.out.println(this.sqlText); 163 } 164 } 165 }else{ 166 parameter.getParameterValue().evaluate(this.getFrameStack(),this); 167 this.sqlText = parameter.getParameterValue().getPlainText(); 168 } 169 }else { 170 // exec a procedure with parameter, put the parameter as a variable into scope 171 TVariable variable = null; 172 int i=0; 173 174 //System.out.println(this.moduleName.toString()); 175 if (this.parameters != null){ 176 if (this.parameters.size() > 0){ 177 for(TExecParameter p:this.parameters){ 178 TObjectName variableName = TObjectName.createObjectName (this.dbvendor, EDbObjectType.variable, new TSourceToken("$"+i)); 179 variable = new TVariable(variableName,p,this.moduleName); 180 variable.setVariableStr(TBaseType.getStringInsideLiteral(p.getParameterValue().toString())); 181 if ((psql != null) && (psql.getStmtScope() != null)) { 182 psql.getStmtScope().addSymbol(variable); 183 }else{ 184 //TODO: execute 中的变量应该放在gloabl scope中吗? 185 this.getGlobalScope().addSymbol(variable); 186 } 187 188 i++; 189 //System.out.println(p.getParameterValue().toString()); 190 } 191 } 192 } 193 }; 194 }else if (node.getExecType() == TBaseType.metExecStringCmd){ 195 this.stringValues = node.getStringValues(); 196 if (this.stringValues.getExpression(0).getExpressionType() == EExpressionType.simple_object_name_t){ 197 TObjectName var = this.stringValues.getExpression(0).getObjectOperand(); 198 if (var.getDbObjectType() == EDbObjectType.variable){ 199 TVariable symbolVariable = TSymbolTableManager.searchSymbolVariable(this.getFrameStack(),var.toString()); 200 if (symbolVariable != null){ 201 //this.getSqlEnv().getVariableValue(symbolVariable.getQualifiedName(),symbolVariable.getVariableStr()); 202 this.sqlText = symbolVariable.getVariableStr(); 203 //System.out.println(this.sqlText); 204 } 205 } 206 } 207 this.linkServerName = node.getLinkServerName(); 208 this.executeAsUser = node.getExecuteAsUser(); 209 this.executeAsLogin = node.getExecuteAsLogin(); 210 }else if (node.getExecType() == TBaseType.metNoExecKeyword){ 211 //the first statement in a batch or an osql or sqlcmd script, EXEC is not required. 212 //dbo.uspGetEmployeeManagers @BusinessEntityID = 6; 213 if (this.sourcetokenlist.size() > 0){ 214 TSourceToken st1 = this.sourcetokenlist.get(0); 215 String errMsg = "syntax error"; 216 TSourceToken errToken = st1; 217 TSyntaxError err = new TSyntaxError(st1.toString(),st1.lineNo,st1.columnNo,"syntax error",EErrorType.sperror 218 ,TBaseType.MSG_ERROR_SYNTAX_ERROR,this,st1.posinlist); 219 if (!isValidProcedureCall(this.sourcetokenlist,err)) 220 this.parseerrormessagehandle( err); 221 222 // moduleName = (TObjectName)this.parser.getNf().createNode(ENodeType.T_ObjectName.getId()); //new TObjectName(); 223 moduleName = new TObjectName(); 224 moduleName.setGsqlparser(this.getGsqlparser()); 225 int j = 0; 226 for(int i=0;i<this.sourcetokenlist.size();i++){ 227 if ((this.sourcetokenlist.get(i).tokentype == ETokenType.ttwhitespace) 228 || (this.sourcetokenlist.get(i).tokentype == ETokenType.ttreturn) 229 ||(this.sourcetokenlist.get(i).tokentype == ETokenType.ttsemicolon) 230 ){ 231 break; 232 } 233 j++; 234 } 235 switch(j){ 236 case 1: 237 moduleName.init(this.sourcetokenlist.get(0)); 238 break; 239 case 3: 240 moduleName.init(this.sourcetokenlist.get(0),this.sourcetokenlist.get(2)); 241 break; 242 case 5: 243 moduleName.init(this.sourcetokenlist.get(0),this.sourcetokenlist.get(2),this.sourcetokenlist.get(4)); 244 break; 245 case 7: 246 moduleName.init(this.sourcetokenlist.get(0),this.sourcetokenlist.get(2),this.sourcetokenlist.get(4),this.sourcetokenlist.get(6)); 247 break; 248 default: 249 moduleName = null; 250 break; 251 } 252 253 if (moduleName != null){ 254 //moduleName.setObjectType(TObjectName.ttobjProcedureName); 255 moduleName.setDbObjectType(EDbObjectType.procedure); 256 } 257 258 } 259 260 } 261 return 0; 262 } 263 264 public TObjectName getLinkServerName() { 265 return linkServerName; 266 } 267 268 private TObjectName linkServerName; 269 270 private TObjectName executeAsUser; 271 private TObjectName executeAsLogin; 272 273 public TObjectName getExecuteAsUser() { 274 return executeAsUser; 275 } 276 277 public TObjectName getExecuteAsLogin() { 278 return executeAsLogin; 279 } 280 281 public void accept(TParseTreeVisitor v){ 282 v.preVisit(this); 283 v.postVisit(this); 284 } 285 public void acceptChildren(TParseTreeVisitor v){ 286 v.preVisit(this); 287 v.postVisit(this); 288 } 289 290 public void setModuleName(TObjectName moduleName) { 291 this.moduleName = moduleName; 292 } 293 294 public void setReturnStatus(TObjectName returnStatus) { 295 this.returnStatus = returnStatus; 296 } 297 298 public void setParameters(TExecParameterList parameters) { 299 this.parameters = parameters; 300 } 301 302 public void setStringValues(TExpressionList stringValues) { 303 this.stringValues = stringValues; 304 } 305 306 public void setExecType(int execType) { 307 this.execType = execType; 308 } 309}