Program with embedded sql gives compilation error - sql

#include<stdio.h>
#include<error.h>
#include<sys/shm.h>
#include "/opt/PostgreSQL/9.1/include/libpq-fe.h"
int main()
{
PGconn *conn;
int buf_ptr=0;
int i;
{
fprintf(stderr,"connection to database failed:%s",PQerrorMessage(conn));
exit(0);
}
else
{
printf("connection to database successful \n");
}
printf("Do you want to create a table enter 1 \n ");
scanf("%d",&i);
if(i==1)
{
EXEC SQl CREATE TABLE EMPOYE(
ENO INT,
ENAME VARCHAR(10));
}
return 0;
}
hello i am a newbie i am learning embedded c
i want to create a simple code where a table is created in c
when i am compiling the above program i am getting error like
embc.c:25: error: âEXECâ undeclared (first use in this function)
embc.c:25: error: (Each undeclared identifier is reported only once
embc.c:25: error: for each function it appears in.)
embc.c:25: error: expected â;â before âSQlâ
please help

First, the connection to database is missing, you should have something like :
int i=0;
EXEC SQL CONNECT TO target [AS connection-name] [USER user-name];
Or
PGconn *conn;
int buf_ptr=0;
int i=0;
conn = PQconnectdbParams(const char **keywords, const char **values, int expand_dbname);
then save your source file as prog.pgc and run :
ecpg prog.pgc
this will create a file called prog.c which can be compiled as a standard C file.

Related

How to handle errors in a select statement when attempting an insert or fail?

Is there a good way to handle errors in a select statement when attempting an insert or fail? Specifically, I want to insert elements into a table, but the select statement used to generate these elements is failing. I would like to have all the elements where the select statement succeeded to be inserted, but for the overall statement to fail. I thought that insert or fail would do this, but it does not. More specifically, imagine if we defined a new SQLite function "log"
#include <string>
#include <sqlite3ext.h>
#include <cmath>
SQLITE_EXTENSION_INIT1
extern "C" {
int sqlite3_log_init(
sqlite3 * db,
char ** err,
sqlite3_api_routines const * const api
);
}
// Compute the log of the input
void mylog(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
// Grab the number
auto num = sqlite3_value_double(argv[0]);
// If positive, take the log
if(num > 0.)
sqlite3_result_double(context, log(num));
// Otherwise, throw an error
else {
auto msg = std::string("Can't take the log of a nonpositive number");
sqlite3_result_error(context,msg.c_str(),msg.size());
}
}
// Initialize the functions
int sqlite3_log_init(
sqlite3 *db,
char **err,
sqlite3_api_routines const * const api
){
SQLITE_EXTENSION_INIT2(api)
// Register the log function
if( int ret = sqlite3_create_function(
db, "log", 1, SQLITE_ANY, 0, mylog, 0, 0)
) {
*err=sqlite3_mprintf("Error registering log: %s",
sqlite3_errmsg(db));
return ret;
}
// If we've made it this far, we should be ok
return SQLITE_OK;
}
This can be compiled with
g++ -std=c++14 log.cpp -shared -o log.so -fPIC
Basically, the above function takes the log of its element. For example,
sqlite> select log(1);
0.0
sqlite> select log(0);
Error: Can't take the log of a nonpositve number
Now, consider the following sequence of SQL operations
sqlite> .load "./log.so"
sqlite> create table foo (num real);
sqlite> insert into foo values (2.), (1.), (0.);
sqlite> create table bar (num real);
sqlite> insert or fail into bar select log(num) from foo;
Error: Can't take the log of a nonpositve number
sqlite> select * from bar;
sqlite>
Basically, the table bar is empty because the select statement failed on 0. What I want to have happen is for the table bar to contain the elements log(2.) and log(1.), but the error to still be thrown. Is there a way to have that happen?
SQLite's ON CONFLICT clause applies only to UNIQUE, NOT NULL, CHECK, and PRIMARY KEY constraints, so you would not be able to use INSERT OR IGNORE.
Once a user-defined function returns an error, it is not possible to suppress it.
You could say that the function's result is undefined, and let it return NULL (which you can then filter out).
Alternatively, get only those rows which have valid values:
INSERT INTO bar SELECT log(num) FROM foo WHERE num > 0;

Thread breakpoint error at custom function

I am trying to compile this simple program on Xcode 5 and I'm getting a "thread 1: breakpoint 1.1" message at error line below. Anyone know how I can fix it?
Here's my code:
#import <Foundation/Foundation.h>
int totalSavings(int listTotal);
int main(int argc, const char * argv[])
{
#autoreleasepool {
int itemEntry, itemEntry1, itemEntry2,
listTotal, calcSavings;
itemEntry = 320;
itemEntry1 = 218;
itemEntry2 = 59;
listTotal = itemEntry + itemEntry1 + itemEntry2;
calcSavings = totalSavings(listTotal); \\error line
NSLog(#"Total Planned Spending: %d \n Amount Saved: %d", listTotal,
calcSavings);
}
return 0;
}
int totalSavings(int listTotal)
{
int savingsTotal;
savingsTotal = 700 - listTotal;
return savingsTotal;
}
Including the type int in the call is incorrect syntax.
The line in error:
calcSavings = totalSavings(int listTotal);
The fixed line:
calcSavings = totalSavings(listTotal);
The error message is:
Untitled.m:16:36: error: expected expression
calcSavings = totalSavings(int listTotal); // error line
^
Notice the "^" just under int, this is a clear indication of where the error is.

transform javascript to opcode using spidermonkey

i am new to spider monkey and want to use it for transform java script file to sequence of byte code.
i get spider monkey and build it in debug mode.
i want to use JS_CompileScript function in jsapi.h to compile javascript code and analysis this to get bytecode , but when in compile below code and run it , i get run time error.
the error is "Unhandled exception at 0x0f55c020 (mozjs185-1.0.dll) in spiderMonkeyTest.exe: 0xC0000005: Access violation reading location 0x00000d4c." and i do not resolve it.
any body can help me to resolve this or introducing other solutions to get byte code from javascript code by using spider monkey ?
// spiderMonkeyTest.cpp : Defines the entry point for the console application.
//
#define XP_WIN
#include <iostream>
#include <fstream>
#include "stdafx.h"
#include "jsapi.h"
#include "jsanalyze.h"
using namespace std;
using namespace js;
static JSClass global_class = { "global",
JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub,
NULL,
JS_PropertyStub,
JS_StrictPropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
NULL,
JSCLASS_NO_OPTIONAL_MEMBERS
};
int _tmain(int argc, _TCHAR* argv[]) {
/* Create a JS runtime. */
JSRuntime *rt = JS_NewRuntime(16L * 1024L * 1024L);
if (rt == NULL)
return 1;
/* Create a context. */
JSContext *cx = JS_NewContext(rt, 8192);
if (cx == NULL)
return 1;
JS_SetOptions(cx, JSOPTION_VAROBJFIX);
JSScript *script;
JSObject *obj;
const char *js = "function a() { var tmp; tmp = 1 + 2; temp = temp * 2; alert(tmp); return 1; }";
obj = JS_CompileScript(cx,JS_GetGlobalObject(cx),js,strlen(js),"code.js",NULL);
script = obj->getScript();
if (script == NULL)
return JS_FALSE; /* compilation error */
js::analyze::Script *sc = new js::analyze::Script();
sc->analyze(cx,script);
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
/* Shut down the JS engine. */
JS_ShutDown();
return 1;
}
Which version of Spidermonkey are you using? I am using the one that comes with FireFox 10 so the API may be different.
You should create a new global object and initialize it by calling JS_NewCompartmentAndGlobalObject() and JS_InitStandardClasses() before compiling your script :
.....
/*
* Create the global object in a new compartment.
* You always need a global object per context.
*/
global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
if (global == NULL)
return 1;
/*
* Populate the global object with the standard JavaScript
* function and object classes, such as Object, Array, Date.
*/
if (!JS_InitStandardClasses(cx, global))
return 1;
......
Note, the function JS_NewCompartmentAndGlobalObject() is obsolete now, check the latest JSAPI documentation for the version your are using. Your JS_CompileScript() call just try to retrieve a global object which has not been created and probably this causes the exception.
how about using function "SaveCompiled" ? it will save object/op-code (compiled javascript) to file

Oracle Pro*C updating table with cursor failed

I have a table like this:
CREATE TABLE book_info (
book_id VARCHAR(32) not null,
title varchar(255) not null,
author varchar(255) not null,
folder_path varchar(255) not null,
primary key(book_id)
);
And i insert this data on it:
insert into book_info values('BOOK1', 'APUE', 'Richard Stevens', '/home/user1/unix_programming_books');
insert into book_info values('BOOK2', 'Unix Network programming', 'Richard Stevens', '/home/user1/unix_programming_books');
insert into book_info values('BOOK3', 'Core Python Applications Programming', 'Wesley J. Chun', '/home/user1/python_programming_books');
I'm trying to update this table using Oracle PRO*C, but i can't! below is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE ORACA;
#define USER_LEN 10
#define PASS_LEN 10
VARCHAR user[USER_LEN];
VARCHAR pass[PASS_LEN];
#define STRCPY_TO_ORA(dest, source)\
dest.len = strlen(source);\
strcpy((char *)dest.arr, (const char *)source)
#define STRCPY_FROM_ORA(dest, source)\
source.arr[source.len] = 0;\
strcpy((char *)dest,(const char *)source.arr)
/* Connecting to the database */
int db_connection(char *db_user, char *db_pass)
{
strncpy((char *) user.arr, db_user, USER_LEN);
user.len = strlen((char *) user.arr);
strncpy((char *) pass.arr, db_pass, PASS_LEN);
pass.len = strlen((char *) pass.arr);
EXEC SQL CONNECT :user IDENTIFIED BY :pass;
if (sqlca.sqlcode != 0)
{
fprintf(stdout, "Connection failed:%s\n", sqlca.sqlerrm.sqlerrmc);
return(sqlca.sqlcode);
}
fprintf(stdout, "Connected to ORACLE as user:%s\n", user.arr);
return (sqlca.sqlcode);
}
int book_not_found_function(char *path)
{
fprintf(stdout, "%s\n", __FUNCTION__);
}
int path_update_success_function(char *book_id, char *new_path)
{
fprintf(stdout, "Update book %s path to %s\n", book_id, new_path);
}
void other_function(void)
{
fprintf(stdout, "%s\n", __FUNCTION__);
}
/* Updating books path */
int books_path_updating(char *old_path, char *new_path)
{
char book_id_string[32];
EXEC SQL BEGIN DECLARE SECTION;
varchar sql_old_path[255];
varchar sql_new_path[255];
varchar sql_book_id[32];
EXEC SQL END DECLARE SECTION;
STRCPY_TO_ORA(sql_old_path, old_path);
STRCPY_TO_ORA(sql_new_path, new_path);
/* Declare a cursor for the FETCH statement. */
EXEC SQL DECLARE books_cursor CURSOR FOR
SELECT BOOK_ID
FROM BOOK_INFO
WHERE FOLDER_PATH = :sql_old_path;
if (sqlca.sqlcode != 0)
{
fprintf(stdout, "Declare cursor failed\n");
fprintf(stdout, "Oracle error %s\n", sqlca.sqlerrm.sqlerrmc);
return(sqlca.sqlcode);
}
EXEC SQL OPEN books_cursor;
if (sqlca.sqlcode != 0)
{
fprintf(stdout, "Open cursor failed\n");
fprintf(stdout, "Oracle error %s\n", sqlca.sqlerrm.sqlerrmc);
return(sqlca.sqlcode);
}
for ( ;; )
{
//EXEC SQL WHENEVER NOT FOUND DO break; // I used it but still nothing
//EXEC SQL WHENEVER NOT FOUND GOTO not_found; // I used this too
//EXEC SQL WHENEVER NOT FOUND DO continue; // I used this too
/* Fetching data */
EXEC SQL FETCH books_cursor
INTO :sql_book_id;
if (sqlca.sqlcode == 1403)
{
fprintf(stdout, "No book found for this folder %s\n", old_path);
book_not_found_function(old_path);
return 0;
}
else if (sqlca.sqlcode != 0)
{
fprintf(stdout, "Oracle error %s\n", sqlca.sqlerrm.sqlerrmc);
EXEC SQL CLOSE books_cursor;
return (sqlca.sqlcode);
}
else
{
STRCPY_FROM_ORA(book_id_string, sql_book_id);
fprintf(stdout, "BOOK_ID = %s\n", book_id_string);
/* Updating the path */
EXEC SQL UPDATE BOOK_INFO
SET FOLDER_PATH =:sql_new_path
WHERE BOOK_ID =:sql_book_id;
if (sqlca.sqlcode != 0)
{
fprintf(stdout, "Oracle error %s\n", sqlca.sqlerrm.sqlerrmc);
EXEC SQL CLOSE books_cursor;
return (sqlca.sqlcode);
}
else
{
path_update_success_function(book_id_string, new_path);
}
}
}
EXEC SQL CLOSE books_cursor;
other_function();
EXEC SQL COMMIT WORK RELEASE;
return 0;
}
int main(int argc, char **argv)
{
db_connection("evariste", "123456");
books_path_updating("/home/user1/unix_programming_books", "/home/user1/UNIX_PROGRAMMING_BOOKS");
books_path_updating("/non_existing_path", "/non_existing_path");
return 0;
}
This program produce the output :
Connected to ORACLE as user:evariste
BOOK_ID = BOOK1
Update book BOOK1 path to /home/user1/UNIX_PROGRAMMING_BOOKS
BOOK_ID = BOOK2
Update book BOOK2 path to /home/user1/UNIX_PROGRAMMING_BOOKS
No book found for this folder /home/user1/unix_programming_books // WHEY THIS?
book_not_found_function // WHY THIS
Declare cursor failed // WHY THIS
Oracle error ORA-01403: no data found // WHY THIS
The table is not updated and the functions path_update_success_function and other_function are never executed! Why this?
Thanks for your help.
Connected to ORACLE as user:evariste
BOOK_ID = BOOK1
Update book BOOK1 path to /home/user1/UNIX_PROGRAMMING_BOOKS
BOOK_ID = BOOK2
Update book BOOK2 path to /home/user1/UNIX_PROGRAMMING_BOOKS
No book found for this folder /home/user1/unix_programming_books // WHEY THIS?
You've fetched past the end of the resultset. Two rows match the cursor this time, so the first two fetches succeed; the third gets no data. This is expected and you shouldn't treat this as an error - just break the loop, which will also cause other_function to be called.
book_not_found_function // WHY THIS
Because you treat 1403 as an error. If you want to call this function when there are no matches, you'll need to count in the loop, and call it afterwards if needed.
Declare cursor failed   // WHY THIS
Oracle error ORA-01403: no data found // WHY THIS
sqlca.sqlcode seems to still be set from the earlier fetch, so this is misleading.
As far as I can remember you'd normally declare the cursor once in the file, not each time the function is called; not sure if Pro*C just ignores the redefinition. You can look at the generated file to see how it deals with it. You also won't get a runtime error from this, if it's wrong it won't (pre-)compile.
The table is not updated and the functions
path_update_success_function and other_function are never executed!
Why this?
path_update_success is called for the first two fetches, but not for the third which fails, and not for the second path because the function returns due to the apparent declare cursor before it gets near it. other_function isn't called because for both calls you return from the function before you can reach it. Similarly the table seems to not be updated because you return before you commit. Unlike SQL*Plus, Pro*C doesn't automatically commit on exit, so there is an implicit rollback. Note also that if you did get to the commit, the release disconnects you, so the second time you'd get a not-connected-to-Oracle error. You should decide to commit/rollback once really, probably right at the end of main.
Untested modification:
int books_path_updating(char *old_path, char *new_path)
{
char book_id_string[32];
int books_found;
EXEC SQL BEGIN DECLARE SECTION;
varchar sql_old_path[255];
varchar sql_new_path[255];
varchar sql_book_id[32];
EXEC SQL END DECLARE SECTION;
STRCPY_TO_ORA(sql_old_path, old_path);
STRCPY_TO_ORA(sql_new_path, new_path);
/* Declare a cursor for the FETCH statement */
EXEC SQL DECLARE books_cursor CURSOR FOR
SELECT BOOK_ID
FROM BOOK_INFO
WHERE FOLDER_PATH = :sql_old_path;
EXEC SQL OPEN books_cursor;
if (sqlca.sqlcode != 0)
{
fprintf(stdout, "Open cursor failed\n");
}
books_found = 0;
while (sqlca.sqlcode == 0)
{
/* Fetching data */
EXEC SQL FETCH books_cursor
INTO :sql_book_id;
if (sqlca.sqlcode != 0)
{
break;
}
STRCPY_FROM_ORA(book_id_string, sql_book_id);
fprintf(stdout, "BOOK_ID = %s\n", book_id_string);
/* Updating the path */
EXEC SQL UPDATE BOOK_INFO
SET FOLDER_PATH = :sql_new_path
WHERE BOOK_ID = :sql_book_id;
if (sqlca.sqlcode != 0)
{
break;
}
/* Track how many books we found, though we only really care later that
* this is non-zero */
books_found++;
path_update_success_function(book_id_string, new_path);
}
EXEC SQL CLOSE books_cursor;
/* Check for and display error, but ignore 1403 as this just indicates the
* end of the result set */
if ((sqlca.sqlcode != 0) && (sqlca.sqlcode != 1403))
{
fprintf(stdout, "Oracle error %s\n", sqlca.sqlerrm.sqlerrmc);
return 1;
}
if (books_found == 0)
{
fprintf(stdout, "No book found for this folder %s\n", old_path);
book_not_found_function(old_path);
return 0;
}
other_function();
return 0;
}
int main(int argc, char **argv)
{
int rc;
rc = db_connection("evariste", "123456");
/* Only do the first path if we didn't get an error connecting */
if (rc == 0)
{
rc == books_path_updating("/home/user1/unix_programming_books",
"/home/user1/UNIX_PROGRAMMING_BOOKS");
}
/* Only do the next path if we didn't get an error from the previous one */
if (rc == 0)
{
rc = books_path_updating("/non_existing_path",
"/non_existing_path");
}
/* Decide whether to rollback or commit; this assumes you don't want to
* keep any changes if there are any errors */
if (rc != 0)
{
EXEC SQL ROLLBACK WORK RELEASE;
return 1;
}
EXEC SQL COMMIT WORK RELEASE;
return 0;
}
Seems DECLARE CURSOR does not set sqlca.sqlcode.
The error you've got was the previous one when you achieved the end of your fetch.
So you should not test errors after a DECLARE CURSOR, but after the OPEN CURSOR only.

Expected identifier or '(' before '.' token

I'm new to Objective-C so I'm using a book to get to grips with it. I'm at a bit where it's explaining structs and I can't for the life of me get them to work.
I have the following code:
int main (int argc, char *argv[])
{
struct node
{
int nodeID;
int x;
int y;
BOOL isActive;
};
typedef struct node myNode;
myNode.nodeID = 1;
}
and I'm getting the error written in the title. Every time I search for this error online I found different variations such as 'before '>' token' or 'before '}' token' but i can't find anything with the '.' token and it's really frustrating and I assume it's somethings ridiculously trivial and basic. Any help would be appreciated.
I believe you're trying to modify the actual type itself. nodeA is now the type of that struct, much like int. You need to do something like nodeA myNode, then you would be able to perform myNode.nodeID = 1 without error.
I've got it sorted now, I used the following and it seems to be fixed now:
int main (int argc, char *argv[])
{
struct node
{
int nodeID;
int x;
int y;
BOOL isActive;
};
struct node myNode;
myNode.nodeID = 1;
myNode.x = 100;
myNode.y = 200;
myNode.isActive = TRUE;
}
Thanks for all your help Darth! :)
I think the problem with the original code was, it was trying to make myNode a type name using typedef. Thus, myNode is NOT a variable that assignment can happen to. Rather, it was another alias for struct node.