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 if ((this.moduleName != null)&&(this.moduleName.toString().equalsIgnoreCase("sp_executesql"))){ 154 TExecParameter parameter = this.parameters.getExecParameter(0); 155 if (parameter.getParameterValue().getExpressionType() == EExpressionType.simple_object_name_t){ 156 TObjectName var = parameter.getParameterValue().getObjectOperand(); 157 if (var.getDbObjectType() == EDbObjectType.variable){ 158 TVariable symbolVariable = TSymbolTableManager.searchSymbolVariable(this.getFrameStack(),var.toString()); 159 if (symbolVariable != null){ 160 this.sqlText = symbolVariable.getVariableStr(); 161 //System.out.println(this.sqlText); 162 } 163 } 164 }else{ 165 parameter.getParameterValue().evaluate(this.getFrameStack(),this); 166 this.sqlText = parameter.getParameterValue().getPlainText(); 167 } 168 }else { 169 // exec a procedure with parameter, put the parameter as a variable into scope 170 TVariable variable = null; 171 int i=0; 172 173 //System.out.println(this.moduleName.toString()); 174 if (this.parameters != null){ 175 if (this.parameters.size() > 0){ 176 for(TExecParameter p:this.parameters){ 177 TObjectName variableName = TObjectName.createObjectName (this.dbvendor, EDbObjectType.variable, new TSourceToken("$"+i)); 178 variable = new TVariable(variableName,p,this.moduleName); 179 variable.setVariableStr(TBaseType.getStringInsideLiteral(p.getParameterValue().toString())); 180 if ((psql != null) && (psql.getStmtScope() != null)) { 181 psql.getStmtScope().addSymbol(variable); 182 }else{ 183 //TODO: execute 中的变量应该放在gloabl scope中吗? 184 this.getGlobalScope().addSymbol(variable); 185 } 186 187 i++; 188 //System.out.println(p.getParameterValue().toString()); 189 } 190 } 191 } 192 }; 193 }else if (node.getExecType() == TBaseType.metExecStringCmd){ 194 this.stringValues = node.getStringValues(); 195 if (this.stringValues.getExpression(0).getExpressionType() == EExpressionType.simple_object_name_t){ 196 TObjectName var = this.stringValues.getExpression(0).getObjectOperand(); 197 if (var.getDbObjectType() == EDbObjectType.variable){ 198 TVariable symbolVariable = TSymbolTableManager.searchSymbolVariable(this.getFrameStack(),var.toString()); 199 if (symbolVariable != null){ 200 //this.getSqlEnv().getVariableValue(symbolVariable.getQualifiedName(),symbolVariable.getVariableStr()); 201 this.sqlText = symbolVariable.getVariableStr(); 202 //System.out.println(this.sqlText); 203 } 204 } 205 } 206 this.linkServerName = node.getLinkServerName(); 207 }else if (node.getExecType() == TBaseType.metNoExecKeyword){ 208 //the first statement in a batch or an osql or sqlcmd script, EXEC is not required. 209 //dbo.uspGetEmployeeManagers @BusinessEntityID = 6; 210 if (this.sourcetokenlist.size() > 0){ 211 TSourceToken st1 = this.sourcetokenlist.get(0); 212 String errMsg = "syntax error"; 213 TSourceToken errToken = st1; 214 TSyntaxError err = new TSyntaxError(st1.toString(),st1.lineNo,st1.columnNo,"syntax error",EErrorType.sperror 215 ,TBaseType.MSG_ERROR_SYNTAX_ERROR,this,st1.posinlist); 216 if (!isValidProcedureCall(this.sourcetokenlist,err)) 217 this.parseerrormessagehandle( err); 218 219 // moduleName = (TObjectName)this.parser.getNf().createNode(ENodeType.T_ObjectName.getId()); //new TObjectName(); 220 moduleName = new TObjectName(); 221 moduleName.setGsqlparser(this.getGsqlparser()); 222 int j = 0; 223 for(int i=0;i<this.sourcetokenlist.size();i++){ 224 if ((this.sourcetokenlist.get(i).tokentype == ETokenType.ttwhitespace) 225 || (this.sourcetokenlist.get(i).tokentype == ETokenType.ttreturn) 226 ||(this.sourcetokenlist.get(i).tokentype == ETokenType.ttsemicolon) 227 ){ 228 break; 229 } 230 j++; 231 } 232 switch(j){ 233 case 1: 234 moduleName.init(this.sourcetokenlist.get(0)); 235 break; 236 case 3: 237 moduleName.init(this.sourcetokenlist.get(0),this.sourcetokenlist.get(2)); 238 break; 239 case 5: 240 moduleName.init(this.sourcetokenlist.get(0),this.sourcetokenlist.get(2),this.sourcetokenlist.get(4)); 241 break; 242 case 7: 243 moduleName.init(this.sourcetokenlist.get(0),this.sourcetokenlist.get(2),this.sourcetokenlist.get(4),this.sourcetokenlist.get(6)); 244 break; 245 default: 246 moduleName = null; 247 break; 248 } 249 250 if (moduleName != null){ 251 //moduleName.setObjectType(TObjectName.ttobjProcedureName); 252 moduleName.setDbObjectType(EDbObjectType.procedure); 253 } 254 255 } 256 257 } 258 return 0; 259 } 260 261 public TObjectName getLinkServerName() { 262 return linkServerName; 263 } 264 265 private TObjectName linkServerName; 266 267 public void accept(TParseTreeVisitor v){ 268 v.preVisit(this); 269 v.postVisit(this); 270 } 271 public void acceptChildren(TParseTreeVisitor v){ 272 v.preVisit(this); 273 v.postVisit(this); 274 } 275 276 public void setModuleName(TObjectName moduleName) { 277 this.moduleName = moduleName; 278 } 279 280 public void setReturnStatus(TObjectName returnStatus) { 281 this.returnStatus = returnStatus; 282 } 283 284 public void setParameters(TExecParameterList parameters) { 285 this.parameters = parameters; 286 } 287 288 public void setStringValues(TExpressionList stringValues) { 289 this.stringValues = stringValues; 290 } 291 292 public void setExecType(int execType) { 293 this.execType = execType; 294 } 295}