How to use non-ASCII-chars in procedure definitions in Firebird 2.5 / error "Malformed string" - firebird

I try to create a procedure that contains non-ASCII-chars in Firebird 2.5.9 but I always get the following error:
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-STORE RDB$PROCEDURES failed
-Malformed string
Here is, what I am trying to do:
isql -user admin -password masterkey
create database "chartest.fdb" default character set win1252
SET NAMES WIN1252;
SET TERM ^ ;
CREATE PROCEDURE PROC_VAL_TO_TEXT (AVAL INTEGER )
RETURNS (RESULT VARCHAR(20) ) AS
begin
if (aval = 0) then
result = 'natürlich';
else
result = 'niemals';
suspend;
end^
SET TERM ; ^
In Firebird 2.0 this is working fine. Why doesn't this work in 2.5 and what can I do to avoid the error?

"SET NAMES" command must be used before "CREATE DATABASE" or "CONNECT" commands to have effect. Also character set in it must exactly match real encoding of the script.

Related

Can't access output variable in command text

Set cmd = Server.CreateObject("ADODB.Command")
With cmd
.ActiveConnection = db
.CommandText = "SELECT #date = '2019-01-01'"
.Parameters.Append(.CreateParameter("#date", adDBDate, adParamOutput))
.Execute
End With
Gives...
Must declare the scalar variable "#date".
Why can't I access the output parameter in the query text?
Named parameters work as expected on both sides (Server: SQL Server, Client: ADODB & VBScript for your case) only if the provider supports it. For SQL Server providers it is supported only with commands configured to call a stored procedure with named parameters (where cmd.CommandType set adCmdStoredProc and cmd.NamedParameters set True).
For an ordinary command like yours, named parameters are not recognized by the server, only the ? placeholders recognized as parameters in the query.
So you should try something like the following.
Set cmd = Server.CreateObject("ADODB.Command")
With cmd
.ActiveConnection = db
.CommandText = "SELECT ? = '2019-01-01'"
.Parameters.Append(.CreateParameter("#dummyForServerNotForClient", adDBDate, adParamOutput))
.Execute
' must print: 2019-01-01
Response.Write .Parameters("#dummyForServerNotForClient").Value
End With
Since the parameter names ignored by servers, you can write the same code by omitting the parameter name, and access the parameter's value by using its ordinal position in the collection. IMHO, with the lack of explicitly named parameters the code becomes more logical and readable.
Set cmd = Server.CreateObject("ADODB.Command")
With cmd
.ActiveConnection = db
.CommandText = "SELECT ? = '2019-01-01'"
.Parameters.Append(.CreateParameter(, adDBDate, adParamOutput))
.Execute
' also must print: 2019-01-01
Response.Write .Parameters(0).Value
End With
I hope this helps you to understand the concept.
The error comes from T-SQL because the variable #date hasn't been declared.
Adjust the T-SQL string you are passing into the ADODB.Command to declare the variable;
Set cmd = Server.CreateObject("ADODB.Command")
With cmd
.ActiveConnection = db
.CommandText = "DECLARE #date AS DATETIME; SELECT #date = '2019-01-01';"
.Parameters.Append(.CreateParameter("#date", adDBDate, adParamOutput))
.Execute
End With
A simple way to debug these types of issues is to use the SQL Server Management Studio to run the query raw.
SELECT #date = '2019-01-01'
If you had tried to run the query without the declaration you would have got the same error with a bit more detail.
Msg 137, Level 15, State 1, Line 1
Must declare the scalar variable "#date".

How to insert a value to postgres database column which contains double quotes and triple quotes

I want to insert a query string into a Postgres database column in the following format
{"enrolled_time":'''SELECT DISTINCT enrolled_time AT TIME ZONE %s FROM alluser'''}
I try this:
UPDATE reports SET raw_query = {"enrolled_time":'''SELECT DISTINCT enrolled_time AT TIME ZONE %s FROM alluser'''} WHERE id=37;
It gives error like
ERROR: syntax error at or near "{"
LINE 1: UPDATE base_reports SET extra_query = {"enrolled_time":'''SE...
When I try using single quotes it throws error like following:
ERROR: syntax error at or near "SELECT"
LINE 1: ...DATE reports SET raw_query = '{"enrolled_time":'''SELECT DIS...
How can I overcome this situation
Use dollar quoting:
UPDATE reports
SET raw_query = $${"enrolled_time":'''SELECT DISTINCT enrolled_time AT TIME ZONE %s FROM alluser'''}$$
WHERE id = 37;

Raw SQL insert with Korma

I want to execute following raw SQL with Korma:
k/exec-raw
["INSERT INTO events ?, VALUES ? ON CONFLICT (id) DO UPDATE SET title = EXCLUDED.title;" [keys values]]
with params equal to:
keys (str "(" (keys->str res) ")")
values (str "(" (serialize (merge res) ", ") ")" )
The both evaluate to correct strings and work in repl.
But in runtime i have following error in psql console:
ERROR: syntax error at or near "$1" at character 20
STATEMENT: INSERT INTO events $1, VALUES $2 ON CONFLICT (id) DO UPDATE SET title = EXCLUDED.title
Can't figure out what's the problem. Anybody have ever done insert with Korma?
PostgreSQL 9.5 + Korma 0.4.2
Only values can be used as parameters in a prepared statement. So to make it work:
INSERT INTO events (column) VALUES (?)
If you want to work it like you do you have to prepare the sql string yourself and make sure you don't have an sql injection.
Please see the manual

PostgreSQL with ODBC: "there is no parameter $1"

I have a insert statement:
INSERT INTO billData (
tmStart, tsDuration, eCallDir, ...
) VALUES (
$1, -- tmStart
$2, -- tsDuration
$3, -- eCallDir
...
);
I use SQLPrepare to compile it, bind parameters by SQLBindParameter, and execute it by SQLExecute.
After all of there steps, the error code 42P02 (there is no parameter $1) was returned.
BTW: I'm also using the almost same code for MS SQL Server and MySQL, and these two DB are working very well, so I believe my code is correct.
PS: the PostgreSQL is v9.1; the psqlODBC is v9.01.0100-1.
============================================================
UPDATE:
And the following error occured: 42601 (syntax error at or near ",") when I'm using '?' as the parameter placholder:
INSERT INTO billData (
tmStart, tsDuration, eCallDir, ...
) VALUES (
?, -- tmStart
?, -- tsDuration
?, -- eCallDir
...
);
============================================================
UPDATE:
According to the suggestion from j.w.r, It works after adding UseServerSidePrepare=1 option to the ODBC connection string.
A lot of thanks :-)
While I am sure prepared statements works well with PostgreSQL ODBC I think something is wrong with this statement code. At first I would remove comments to make this INSERT as simple as possible. I have just tried multiline INSERT with comments and with colon at ends and it worked well. I converted a little my test Python code:
import odbc
db = odbc.odbc('odbcalias/user/password')
c = db.cursor()
r = c.execute("""INSERT INTO billData (
tmStart, tsDuration, eCallDir, ...
) VALUES (
?, -- tmStart
?, -- tsDuration
?, -- eCallDir
...
);""", (tmStart, tsDuration, eCallDir, ))
print('records inserted: %s' % (r))
Can you try it with ActivePython 2.7 (it already has odbc module)?
If it will work then enable ODBC tracing and test this program. In odbc sql trace file should be entries like:
...
python.exe odbc 924-e8c ENTER SQLExecDirect
HSTMT 00A029A8
UCHAR * 0x00B5A480 [ -3] "INSERT INTO test_table(txt) VALUES (?)\ 0"
SDWORD -3
python.exe odbc 924-e8c EXIT SQLExecDirect with return code 0 (SQL_SUCCESS)
HSTMT 00A029A8
UCHAR * 0x00B5A480 [ -3] "INSERT INTO test_table(txt) VALUES (?)\ 0"
SDWORD -3
python.exe odbc 924-e8c ENTER SQLNumResultCols
HSTMT 00A029A8
SWORD * 0x0021FAA0
python.exe odbc 924-e8c EXIT SQLNumResultCols with return code 0 (SQL_SUCCESS)
HSTMT 00A029A8
SWORD * 0x0021FAA0 (0)
python.exe odbc 924-e8c ENTER SQLRowCount
HSTMT 00A029A8
SQLLEN * 0x0021FBDC
python.exe odbc 924-e8c EXIT SQLRowCount with return code 0 (SQL_SUCCESS)
HSTMT 00A029A8
SQLLEN * 0x0021FBDC (1)
Then make similar trace for your application and try to locate what is different.
============================================================
UPDATE:
According to the suggestion from j.w.r, It works after adding UseServerSidePrepare=1 option to the ODBC connection string.
A lot of thanks :-)
Note: the ByteaAsLongVarBinary=1 option should also be added if you want to parameterize a bytea field with SQLBindParameter.

Why can't I enter a NULL value using Numeric or Date type in Postgresql?

I'm doing a little application for the work and it includes a form. When the person using the form doesn't put a value in a data type "numeric" (lets say a PIN number) or even a date in one of my "date" Data Type fields (lets say his anniverssary), it returns me with the errors as follow:
Error Type – Type d'erreur
_Microsoft OLE DB Provider for ODBC Drivers (0x80004005)_
ERROR: invalid input syntax for type numeric: ""; Error while executing the query
Error Type – Type d'erreur
_Microsoft OLE DB Provider for ODBC Drivers (0x80004005)_
ERROR: syntax error at or near ")"; Error while executing the query
So it seems that when the person using the form enters nothing, it returns the string "empty" that is "".
Why can't the numeric type and data type read that as a NULL entry? These fields are not mandatory and so I need to have them be sometimes blank.
How can I make it possible? Is their a way to keep using "numeric" and "date" type so that when the user enters nothing in those fields, the table fills with a blank case insted of giving me this error?
Here is my sql statement :
trsConn.EXECUTE "INSERT INTO ""TRS"".employeetbl ( "& _
"""firstName"", " & _
"""lastName"" , " & _
"""detContract"", " & _
"sle, " & _
"""posNumber"" "& _
") VALUES (" & _
"'" & Request.Form("empFirst") & "', " & _**
"'" & Replace(Request.Form("empLast"), "'", "`") & "', " & _
"'" & Request.Form("dateContract") & "', " & _
"'" & Request.Form("sle") & "', " & _
"'" & Request.Form("posNum") & "');"
(The posNum and dateContract are both respectivly of type "numeric" and "date"
Thanks so much for the help. Looking forward for hearing what you geniuses have to say.
The concept of NULL in SQL is pretty muddled and inconsistent ... but it's very clear that '' is distinct from NULL.
'' isn't NULL, it's '', the empty string. You can't convert it to a date, number, etc:
regress=# SELECT CAST('' AS DATE);
ERROR: invalid input syntax for type date: ""
LINE 1: SELECT CAST('' AS DATE);
^
regress=# SELECT CAST('' AS NUMERIC);
ERROR: invalid input syntax for type numeric: ""
LINE 1: SELECT CAST('' AS NUMERIC);
^
Some products - notably Microsoft Access and old versions of MySQL - are confused about that matter. NULL is NULL, '' is the empty string; they aren't the same thing. You can't convert one to the other.
So it seems that when the person using the form enters nothing, it
returns the string "empty" that is "". Why can't the numeric type and
data type read that as a NULL entry? These fields are not mandatory
and so I need to have them be sometimes blank.
That's your application's job. When your app it sees the empty string come in on a form field for a numeric, date, or similar, it should send NULL to the database, not ''. That's normally a routine part of converting data from user input before it's supplied to the database. It is vital that you do such conversion; you should never just send values from the user straight to the database.
A quick search suggests that asp classic uses null or undefined as its null values; you should be able to pass them into your prepared statements when something is null.
The fact that you get a syntax error after the error about '' suggests that you're building your SQL statements as strings, not using prepared statements with placeholders. (Thanks JayC for the SO question ref). This is begging for SQL injection; in other words your application is critically insecure. Imagine what happens if the user enters the "date":
2012-01-01'); DROP SCHEMA public;--
and your app happily turns that into
INSERT INTO sometable (blah, blah, blah) VALUES (1, 2, DATE '2012-01-01'); DROP SCHEMA public;--');
The DROP SCHEMA then merrily executes and whoops, splat, there goes your database. That's just the dumbest, simplest kind of SQL injection attack too.