How to run SQLite3 'PRAGMA' commands via C-API? - sql

Inside my C-program, I need to run the following pragma command:
const char *sql = "PRAGMA table_info(family)"; /* 'family' is the table name */
But whether i try to run this sql via sqlite3_exec() routine or sqlite3_prepare_v2() routine, my program stops responding/working at Windows command-prompt (it's a simple 'console program' in c-language).
Interestingly, when i run that same pragma sql at command-prompt normally by running the sqlite3.exe itself, it runs just fine and gives following output:
sqlite> pragma table_info(family);
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 id INTEGER 0 1
1 name TEXT 1 0
2 nickname TEXT 1 0
3 dob TEXT 1 CURRENT_TI 0
But inside my own c-program it doesn't. I have done a bit research about this problem. Both Googling and SQLite Documentation point towards this page here at the official docs. But unfortunately the given information there hasn't enabled me enough to resolve the problem. How can we successfully run SQLite3 'PRAGMA' commands via C-API?
EDIT: Here are the actual problematic lines of code. OR MCVE
I have found the reasons of my program's failure, and have fixed it (Courtesy of clues and leads in Murphy's answer. But for those interested in reproducing the problem, here are the actual lines of code which were causing program to "crash".
Inside my callback function for sqlite3_exec() routine, I had this piece of code(for-loop) for printing ' ---------- ' characters below column names to mimic ".mode column" & ".headers on" style of output in sqlite3 console.
int h;
for(h=0; h <= (strlen(col_value[i])+5); h++)
printf("-");
The problem was being caused by strlen() while printing 'headers' for PRAGMA sql's result column dflt_value which is null for first three columns in my table. If i stop running strlen() on dflt_value. the program runs fine. Similarly, in sqlite3_prepare_v2() routine the problem was being caused by the following lines:
int h;
for(h=0; h <= (strlen(sqlite3_column_text(stmt, 4))+5); h++)
printf("-");
If i remove or comment these lines, all runs well - albeit without ".headers on" style.

sqlite3_exec() should indeed be the way to go to execute pragma commands. You didn't give a MCVE (shame on you!), but I suspect that you either neglect handling error values, or something else is wrong with your code. You should try debugging it.

Related

Oracle SQLPlus: Echo without line numbers?

I'm working on a solution where several SQL and PL/SQL scripts are being run together, in a batch of sorts, via SQL*Plus.
I'm declaring SET ECHO OFF; and SET ECHO ON; at relevant points in the scripts so as to output relevant code.
Currently the output looks something like this:
SQL> DECLARE
2 ct number := 0;
3 ctChanges number := 0;
4
5 BEGIN
6 select count(*) into ct from ...
7 (...rest of code block...)
"some specific status message"
Commit executed.
We keep this output as a run-log in our build-environment, but can also access it as a plain text file.
One downside of this format however, is that if I'd like to copy a certain section of the code and run it again in an IDE (like Toad or SQL Developer), it's hard to exclude the line numbers.
Is it possible to tell SQL*Plus to output the code as above, but without including the line numbers?
You can use options sqlnumber and sqlprompt:
set sqlprompt ''
set sqlnumber off
SET SQLN[UMBER] {ON|OFF}
SET SQLNUMBER is not supported in iSQL*Plus
Sets the prompt for the second and subsequent lines of a SQL command or PL/SQL block. ON sets the prompt to be the line number. OFF sets the prompt to the value of SQLPROMPT.

three dots menu of some sort windows sqlite3

When I try ls -1 (in powershell) to try and get into my table and check it, I get some sort of menu "...>" that I can't .quit out of. when I close out and run sqlite3 -init ex1.sql ex1.db (my example I'm working with, I get " Error: near line 1: table person already exists " when it in fact, does not. how do I get out of this menu, and how do I fix my code? Also, what IS this menu?
My sql code:
CREATE TABLE person (
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT,
age INTEGER
);
...> is shown by the sqlite3 command-line shell (not PowerShell) when you have not finished the current SQL command. Typically, you forgot the terminating ;, or you forgot a ' and are still inside a string.
Maybe you didn't specify what is the database in which you are working. For example before creating the table, use .open <name_database.db> and after run you CREATE TABLE statements.
Also the 3 dots ...> means that you didn't write the complete command, most often you didn't put the semicolon ; or you didn't close well the '. You can exit from this menu by killing the process or complete the command.

while [[ condition ]] stalls on loop exit

I have a problem with ksh in that a while loop is failing to obey the "while" condition. I should add now that this is ksh88 on my client's Solaris box. (That's a separate problem that can't be addressed in this forum. ;) I have seen Lance's question and some similar but none that I have found seem to address this. (Disclaimer: NO I haven't looked at every ksh question in this forum)
Here's a very cut down piece of code that replicates the problem:
1 #!/usr/bin/ksh
2 #
3 go=1
4 set -x
5 tail -0f loop-test.txt | while [[ $go -eq 1 ]]
6 do
7 read lbuff
8 set $lbuff
9 nwords=$#
10 printf "Line has %d words <%s>\n" $nwords "${lbuff}"
11 if [[ "${lbuff}" = "0" ]]
12 then
13 printf "Line consists of %s; time to absquatulate\n" $lbuff
14 go=0 # Violate the WHILE condition to get out of loop
15 fi
16 done
17 printf "\nLooks like I've fallen out of the loop\n"
18 exit 0
The way I test this is:
Run loop-test.sh in background mode
In a different window I run commands like "echo some nonsense >>loop_test.txt" (w/o the quotes, of course)
When I wish to exit, I type "echo 0 >>loop-test.txt"
What happens? It indeed sets go=0 and displays the line:
Line consists of 0; time to absquatulate
but does not exit the loop. To break out I append one more line to the txt file. The loop does NOT process that line and just falls out of the loop, issuing that "fallen out" message before exiting.
What's going on with this? I don't want to use "break" because in the actual script, the loop is monitoring the log of a database engine and the flag is set when it sees messages that the engine is shutting down. The actual script must still process those final lines before exiting.
Open to ideas, anyone?
Thanks much!
-- J.
OK, that flopped pretty quick. After reading a few other posts, I found an answer given by dogbane that sidesteps my entire pipe-to-while scheme. His is the second answer to a question (from 2013) where I see neeraj is using the same scheme I'm using.
What was wrong? The pipe-to-while has always worked for input that will end, like a file or a command with a distinct end to its output. However, from a tail command, there is no distinct EOF. Hence, the while-in-a-subshell doesn't know when to terminate.
Dogbane's solution: Don't use a pipe. Applying his logic to my situation, the basic loop is:
while read line
do
# put loop body here
done < <(tail -0f ${logfile})
No subshell, no problem.
Caveat about that syntax: There must be a space between the two < operators; otherwise it looks like a HEREIS document with bad syntax.
Er, one more catch: The syntax did not work in ksh, not even in the mksh (under cygwin) which emulates ksh93. But it did work in bash. So my boss is gonna have a good laugh at me, 'cause he knows I dislike bash.
So thanks MUCH, dogbane.
-- J
After articulating the problem and sleeping on it, the reason for the described behavior came to me: After setting go=0, the control flow of the loop still depends on another line of data coming in from STDIN via that pipe.
And now that I have realized the cause of the weirdness, I can speculate on an alternative way of reading from the stream. For the moment I am thinking of the following solution:
Open the input file as STDIN (Need to research the exec syntax for that)
When the condition occurs, close STDIN (Again, need to research the syntax for that)
It should then be safe to use the more intuitive:while read lbuffat the top of the loop.
I'll test this out today and post the result. I'd hope someone else benefit from the method (if it works).

Clear Screen in SQL*Plus

I'm running the following report but getting an error
/* Simple table formatting */
clear screen;
accept Report_File char prompt 'Enter a file name for summary report ';
/*Set up column headers*/
col StoreCode format A8 heading 'Store Code';
col DESCRIPTION format A8 heading 'Item Description';
col PRICE format $999999.99 heading 'Price';
col QUANTITY format 999 heading 'Quantity';
col (Price*Quantity) format $999999.99 heading 'Value';
/*Format and title pages */
set Pause off;
set Feedback off;
set Space 6;
set newpage 2;
set pagesize 54;
set linesize 200;
set underline =;
title center 'Current Stock Value by Store' skip 2 left -
'prepared by Jason Kemeys' &Report_Officer right -
&Todays_Date skip4;
btitle center format 999 SQL.PNO;
/* Set breaks and computes */
break on StoreCode skip 2 on SuppCode skip 1 on Report;
compute sum of (Price*Quantity) on StoreCode;
compute sum of (Price*Quantity) on Report;
/*Select data & send to file*/
spool &Report_File;
select StoreCode, Description, Quantity, Price, (Price*Quantity)
from Stocks
order by StoreCode;
spool off;
/* Clear all settings */
clear breaks;
clear columns;
clear computes;
set Pause on;
Just need to know why its showing the error and how to get it running; first time doing a report in SQL.
This is the error I'm getting
clear screen;
* ERROR at line 2: ORA-00900: invalid SQL statement
cl scr is the command used to clear screen in SQL.
I suspect this is dependent on the version of Oracle you are using.
This should work in version 11.2 but to quote from the 10g documentation:
CLEAR SCREEN is not available in SQL*Plus.
The same note isn't there in the 11.1 documentation, which would imply that you're using Oracle 10g or earlier. If this supposition is true then there's little that you can do.
It's possible that you can utilise the host command in SQL*Plus to run cls, if you're using Windows, or clear, if you're using Linux, but I'm not certain that it would have exactly the same effect. If it were possible it would simply be:
host cls
host runs an operating system command from SQL*Plus, and so will appear to clear the screen.
simply use cl scr command to clear the SQL plus.
Very few occurances of ";" in your code is actually needed. For example, the "clear screen" command to start with, doesn't need a semicolon. It will work, when you add one, but I wouldn't be sure about all the subsequent commands in that same file. Commands that need them, are limited to INSERT, UPDATE, DELETE, COMMIT, ROLLBACK, and such.
Secondly, if you get weird feedback from SQL-files, and if you have written them outside of Linux/Unix, this often ends up in SQLPLUS complaining about invisible characters. Look at that file via both VI and CAT commands, and note anything weird.

powershell assigning output of a ps1 script to a variable

Let me start with I am very new to powershell and programming for that matter. I have a powershell script that takes some arguments and that outputs a value.
The result of the script is going to be something like 9/10 where 9 would be the number active out of the total amount of nodes. I want to assign the output to a variable so I can then call another script based on the value.
This is what I have tried, but it does not work:
$active = (./MyScript.ps1 lb uid **** site)
I have also tried the following which seems to assign the variable an empty string
$active = (./MyScript.ps1 lb uid **** site | out-string)
In both cases they run and give me the value immediately instead of assigning it to the variable. When I call the variable, I get no data.
I would embrace PowerShell's object-oriented nature and rather than output a string like "9/10", create an object with properties like NumActiveNodes and TotalNodes e.g. in your script output like so:
new-object psobject -Property #{NumActiveNodes = 9; TotalNodes = 10}
Of course, substitute in the dynamic values for num active and total nodes. Note that uncaptured objects will automatically appear on your script's output. Then, if this is your scripts only output, you can do this:
$obj = .\MyScript.ps1
$obj.NumActiveNodes
9
$obj.TotalNodes
10
It will make it nicer for those consuming the output of your script. In fact the output is somewhat self-documenting e.g.:
C:\PS> .\MyScript.ps1
NumActiveNodes TotalNodes
-------------- ----------
9 10
P.S. When did StackOverflow start sucking so badly at formatting PowerShell script?
If you don't want to change the script ( and assuming only that $avail_count/$total_count line is written by the script), you can do:
$var= powershell .\MyScript.ps1
Or just drop the write-host and have just $avail_count/$total_count
and then do:
$var = .\MyScript.ps1
you could just do a $global:foobar in your script and it will persist after the script is closed
I know, the question is a bit older, but it might help someone to find the right answer.
I had the similar problem with executing PS script with another PS script and saving the output into variable, here are 2 VERY good answers:
Mathias
mklement0
Hope it helps!
Please up-vote them if so, because they are really good!