📄 execute.c
字号:
{ free_params(paramValues, nParams, false, stmt->lineno); return false; } tobeinserted = NULL; } } if (desc_counter == 0) var = var->next; } /* Check if there are unmatched things left. */ if (next_insert(stmt->command, position, stmt->questionmarks) >= 0) { ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL); free_params(paramValues, nParams, false, stmt->lineno); return false; } /* The request has been build. */ if (stmt->connection->committed && !stmt->connection->autocommit) { results = PQexec(stmt->connection->connection, "begin transaction"); if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat)) { free_params(paramValues, nParams, false, stmt->lineno); return false; } PQclear(results); stmt->connection->committed = false; } ecpg_log("ecpg_execute line %d: QUERY: %s with %d parameter on connection %s \n", stmt->lineno, stmt->command, nParams, stmt->connection->name); if (stmt->statement_type == ECPGst_execute) { results = PQexecPrepared(stmt->connection->connection, stmt->name, nParams, paramValues, NULL, NULL, 0); ecpg_log("ecpg_execute line %d: using PQexecPrepared for %s\n", stmt->lineno, stmt->command); } else { if (nParams == 0) { results = PQexec(stmt->connection->connection, stmt->command); ecpg_log("ecpg_execute line %d: using PQexec\n", stmt->lineno); } else { results = PQexecParams(stmt->connection->connection, stmt->command, nParams, NULL, paramValues, NULL, NULL, 0); ecpg_log("ecpg_execute line %d: using PQexecParams \n", stmt->lineno); } } free_params(paramValues, nParams, true, stmt->lineno); if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat)) return (false); var = stmt->outlist; switch (PQresultStatus(results)) { int nfields, ntuples, act_field; case PGRES_TUPLES_OK: nfields = PQnfields(results); sqlca->sqlerrd[2] = ntuples = PQntuples(results); ecpg_log("ecpg_execute line %d: Correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields); status = true; if (ntuples < 1) { if (ntuples) ecpg_log("ecpg_execute line %d: Incorrect number of matches: %d\n", stmt->lineno, ntuples); ecpg_raise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); status = false; break; } if (var != NULL && var->type == ECPGt_descriptor) { struct descriptor *desc = ecpg_find_desc(stmt->lineno, var->pointer); if (desc == NULL) status = false; else { if (desc->result) PQclear(desc->result); desc->result = results; clear_result = false; ecpg_log("ecpg_execute putting result (%d tuples) into descriptor '%s'\n", PQntuples(results), (const char *) var->pointer); } var = var->next; } else for (act_field = 0; act_field < nfields && status; act_field++) { if (var != NULL) { status = ecpg_store_result(results, act_field, stmt, var); var = var->next; } else if (!INFORMIX_MODE(stmt->compat)) { ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS, NULL); return (false); } } if (status && var != NULL) { ecpg_raise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS, NULL); status = false; } break; case PGRES_COMMAND_OK: status = true; cmdstat = PQcmdStatus(results); sqlca->sqlerrd[1] = PQoidValue(results); sqlca->sqlerrd[2] = atol(PQcmdTuples(results)); ecpg_log("ecpg_execute line %d Ok: %s\n", stmt->lineno, cmdstat); if (stmt->compat != ECPG_COMPAT_INFORMIX_SE && !sqlca->sqlerrd[2] && (!strncmp(cmdstat, "UPDATE", 6) || !strncmp(cmdstat, "INSERT", 6) || !strncmp(cmdstat, "DELETE", 6))) ecpg_raise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); break; case PGRES_COPY_OUT: { char *buffer; int res; ecpg_log("ecpg_execute line %d: Got PGRES_COPY_OUT\n", stmt->lineno); while ((res = PQgetCopyData(stmt->connection->connection, &buffer, 0)) > 0) { printf("%s", buffer); PQfreemem(buffer); } if (res == -1) { /* COPY done */ PQclear(results); results = PQgetResult(stmt->connection->connection); if (PQresultStatus(results) == PGRES_COMMAND_OK) ecpg_log("ecpg_execute line %d: Got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno); else ecpg_log("ecpg_execute line %d: Got error after PGRES_COPY_OUT: %s", PQresultErrorMessage(results)); } break; } default: /* * execution should never reach this code because it is already * handled in ECPGcheck_PQresult() */ ecpg_log("ecpg_execute line %d: Got something else, postgres error.\n", stmt->lineno); ecpg_raise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat); status = false; break; } if (clear_result) PQclear(results); /* check for asynchronous returns */ notify = PQnotifies(stmt->connection->connection); if (notify) { ecpg_log("ecpg_execute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n", stmt->lineno, notify->relname, notify->be_pid); PQfreemem(notify); } return status;}boolECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...){ va_list args; struct statement *stmt; struct connection *con; bool status; char *oldlocale; enum ECPGttype type; struct variable **list; enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st; char *prepname; if (!query) { ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL); return (false); } /* Make sure we do NOT honor the locale for numeric input/output */ /* since the database wants the standard decimal point */ oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno); setlocale(LC_NUMERIC, "C");#ifdef ENABLE_THREAD_SAFETY ecpg_pthreads_init();#endif con = ecpg_get_connection(connection_name); if (!ecpg_init(con, connection_name, lineno)) { setlocale(LC_NUMERIC, oldlocale); ecpg_free(oldlocale); return (false); } /* construct statement in our own structure */ va_start(args, query); /* * create a list of variables The variables are listed with input * variables preceding outputvariables The end of each group is marked by * an end marker. per variable we list: type - as defined in ecpgtype.h * value - where to store the data varcharsize - length of string in case * we have a stringvariable, else 0 arraysize - 0 for pointer (we don't * know the size of the array), 1 for simple variable, size for arrays * offset - offset between ith and (i+1)th entry in an array, normally * that means sizeof(type) ind_type - type of indicator variable ind_value * - pointer to indicator variable ind_varcharsize - empty ind_arraysize - * arraysize of indicator array ind_offset - indicator offset */ if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno))) { setlocale(LC_NUMERIC, oldlocale); ecpg_free(oldlocale); va_end(args); return false; } /* * If statement type is ECPGst_prepnormal we are supposed to prepare the * statement before executing them */ if (statement_type == ECPGst_prepnormal) { if (!ecpg_auto_prepare(lineno, connection_name, compat, questionmarks, &prepname, query)) return (false); /* * statement is now prepared, so instead of the query we have to * execute the name */ stmt->command = prepname; statement_type = ECPGst_execute; } else stmt->command = ecpg_strdup(query, lineno); stmt->name = NULL; if (statement_type == ECPGst_execute) { /* if we have an EXECUTE command, only the name is send */ char *command = ecpg_prepared(stmt->command, con, lineno); if (command) { stmt->name = stmt->command; stmt->command = ecpg_strdup(command, lineno); } else ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command); } stmt->connection = con; stmt->lineno = lineno; stmt->compat = compat; stmt->force_indicator = force_indicator; stmt->questionmarks = questionmarks; stmt->statement_type = statement_type; list = &(stmt->inlist); type = va_arg(args, enum ECPGttype); while (type != ECPGt_EORT) { if (type == ECPGt_EOIT) list = &(stmt->outlist); else { struct variable *var, *ptr; if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno))) { setlocale(LC_NUMERIC, oldlocale); ecpg_free(oldlocale); free_statement(stmt); va_end(args); return false; } var->type = type; var->pointer = va_arg(args, char *); var->varcharsize = va_arg(args, long); var->arrsize = va_arg(args, long); var->offset = va_arg(args, long); if (var->arrsize == 0 || var->varcharsize == 0) var->value = *((char **) (var->pointer)); else var->value = var->pointer; /* * negative values are used to indicate an array without given * bounds */ /* reset to zero for us */ if (var->arrsize < 0) var->arrsize = 0; if (var->varcharsize < 0) var->varcharsize = 0; var->next = NULL; var->ind_type = va_arg(args, enum ECPGttype); var->ind_pointer = va_arg(args, char *); var->ind_varcharsize = va_arg(args, long); var->ind_arrsize = va_arg(args, long); var->ind_offset = va_arg(args, long); if (var->ind_type != ECPGt_NO_INDICATOR && (var->ind_arrsize == 0 || var->ind_varcharsize == 0)) var->ind_value = *((char **) (var->ind_pointer)); else var->ind_value = var->ind_pointer; /* * negative values are used to indicate an array without given * bounds */ /* reset to zero for us */ if (var->ind_arrsize < 0) var->ind_arrsize = 0; if (var->ind_varcharsize < 0) var->ind_varcharsize = 0; /* if variable is NULL, the statement hasn't been prepared */ if (var->pointer == NULL) { ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL); ecpg_free(var); setlocale(LC_NUMERIC, oldlocale); ecpg_free(oldlocale); free_statement(stmt); va_end(args); return false; } for (ptr = *list; ptr && ptr->next; ptr = ptr->next); if (ptr == NULL) *list = var; else ptr->next = var; } type = va_arg(args, enum ECPGttype); } va_end(args); /* are we connected? */ if (con == NULL || con->connection == NULL) { free_statement(stmt); ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : "<empty>"); setlocale(LC_NUMERIC, oldlocale); ecpg_free(oldlocale); return false; } /* initialize auto_mem struct */ ecpg_clear_auto_mem(); status = ecpg_execute(stmt); free_statement(stmt); /* and reset locale value so our application is not affected */ setlocale(LC_NUMERIC, oldlocale); ecpg_free(oldlocale); return (status);}/* old descriptor interface */boolECPGdo_descriptor(int line, const char *connection, const char *descriptor, const char *query){ return ECPGdo(line, ECPG_COMPAT_PGSQL, true, connection, '\0', 0, (char *) query, ECPGt_EOIT, ECPGt_descriptor, descriptor, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL, 0L, 0L, 0L, ECPGt_EORT);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -