I am trying to create my first procedure on firebird 2.5 by using ibexpert gui.
The procedure will return 'PROCESS_DATE' which belongs to a specific 'PROCESS_ID'. I prepared following code:
begin
OUTPUT_DATE = (select PROCESS_DATE from PROCESSES
where PROCESS_ID = INPUT_ID);
suspend;
end
input parameter : 'INPUT_ID' --> type 'INTEGER'
output parameter : 'OUTPUT_DATE' --> type 'DATE'
But when I tried to compile it returns this error:
Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
INPUT_ID.
At line 9, column 48.
I do not know how to deal with this error.
I tried to find solutions on other questions also the internet but i couldn't find a basic, understandable answer for beginners. thanks for helps.
Try this:
CREATE PROCEDURE MyP (INPUT_ID INTEGER)
RETURNS (OUTPUT_DATE DATE)
AS
BEGIN
FOR
SELECT PROCESS_DATE FROM PROCESSES
WHERE PROCESS_ID = :INPUT_ID
INTO :OUTPUT_DATE
DO
SUSPEND;
END
Always prepend parameter names with ":". The only place where ":" is not allowed is at the left side of "=" operator.
Related
Using Microsoft Visual FoxPro 9, I have a custom function, "newid()", inside of the stored procedures for Main:
function newId
parameter thisdbf
regional keynm, newkey, cOldSelect, lDone
keynm=padr(upper(thisdbf),50)
cOldSelect=alias()
lDone=.f.
do while not lDone
select keyvalue from main!idkeys where keyname=keynm into array akey
if _tally=0
insert into main!idkeys (keyname) value (keynm)
loop
endif
newkey=akey+1
update main!idkeys set keyvalue=newkey where keyname=keynm and keyvalue=akey
if _tally=1
lDone=.t.
endif
enddo
if not empty(cOldSelect)
select &cOldSelect
else
select 0
endif
return newkey
This function is used to generate a new ID for records added to the database.
It is called as the default value:
I would like to call this newid() function and retrieve its returned value. When executing SELECT newid("TABLENAME"), the error is is thrown:
Invalid subscript reference
How can I call the newid() function and return the newkey in Visual FoxPro 9?
As an addition to what Stefan Wuebbe said,
You actually had your answer in your previous question here that you forgot to update.
From your previous question, as I understand you are coming from a T-SQL background. While in T-SQL (and in SQL generally) there is:
Select < anyVariableOrFunction >
that returns a single column, single row result, in VFP 'select' like that has another meaning:
Select < aliasName >
aliasName is an alias of a working area (or it could be number of a work area) and is used to change the 'current workarea'. When it was used in xBase languages like FoxPro (and dBase), those languages didn't yet meet ANSI-SQL if I am not wrong. Anyway, in VFP there are two Select, this one and SELECT—SQL which definitely requires a FROM clause.
VFP has direct access to variables and function calls though, through the use of = operator.
SELECT newid("TABLENAME")
in T-SQL, would be (you are just displaying the result):
? newid("TABLENAME")
To store it in a variable, you would do something like:
local lnId
lnId = newid("TABLENAME")
* do something with m.lnId
* Note the m. prefix, it is a built-in alias for memory variables
After having said all these, as per your code.
It looks like it has been written by a very old FoxPro programmer and I must admit I am seeing it the first time in my life that someone used "REGIONAL" keyword in VFP. It is from FoxPro 2.x days I know but I didn't see anyone use it up until now :) Anyway, that code doesn't seem to be robust enough in a multiuser environment, you might want to change it. VFP ships with a NewId sample code and below is the slightly modified version that I have been using in many locations and proved to be reliable:
Function NewID
Lparameters tcAlias,tnCount
Local lcAlias, lnOldArea, lcOldReprocess, lcTable, lnTagNo, lnNewValue, lnLastValue, lcOldSetDeleted
lnOldArea = Select()
lnOldReprocess = Set('REPROCESS')
* Uppercase Alias name
lcAlias = Upper(Iif(Parameters() = 0, Alias(), tcAlias))
* Lock reprocess - try once
Set Reprocess To 1
If !Used("IDS")
Use ids In 0
Endif
* If no entry yet create
If !Seek(lcAlias, "Ids", "tablename")
Insert Into ids (tablename, NextID) Values (lcAlias,0)
Endif
* Lock, increment id, unlock, return nextid value
Do While !Rlock('ids')
* Delay before next lock trial
lnStart = Seconds()
Do While Seconds()-lnStart < 0.01
Enddo
Enddo
lnLastValue = ids.NextID
lnNewValue = m.lnLastValue + Evl(m.tnCount,1)
*Try to query primary key tag for lcAlias
lcTable = Iif( Used(lcAlias),Dbf(lcAlias), Iif(File(lcAlias+'.dbf'),lcAlias,''))
lcTable = Evl(m.lcTable,m.lcAlias)
If !Empty(lcTable)
Use (lcTable) In 0 Again Alias '_GetPKKey_'
For m.lnTagNo=1 To Tagcount('','_GetPKKey_')
If Primary(m.lnTagNo,'_GetPKKey_')
m.lcOldSetDeleted = Set("Deleted")
Set Deleted Off
Select '_GetPKKey_'
Set Order To Tag (Tag(m.lnTagNo,'_GetPKKey_')) ;
In '_GetPKKey_' Descending
Locate
lnLastValue = Max(m.lnLastValue, Evaluate(Key(m.lnTagNo,'_GetPKKey_')))
lnNewValue = m.lnLastValue + Evl(m.tnCount,1)
If Upper(m.lcOldSetDeleted) == 'ON'
Set Deleted On
Endif
Exit
Endif
Endfor
Use In '_GetPKKey_'
Select ids
Endif
* Increment
Replace ids.NextID With m.lnNewValue In 'ids'
Unlock In 'ids'
Select (lnOldArea)
Set Reprocess To lnOldReprocess
Return ids.NextID
Endfunc
Note: If you use this, as I see from your code, you would need to change the "id table" name to idkeys, field names to keyname, keyvalue:
ids => idKeys
tablename => keyName
nextId => keyValue
Or in your database just create a new table with this code:
CREATE TABLE ids (TableName c(50), NextId i)
INDEX on TableName TAG TableName
When executing SELECT newid("TABLENAME")
The error: Invalid subscript reference is thrown
The SQL Select command in Vfp requires a From clause.
Running a procedure or a function can, or better usually needs to be done differently:
For example, in the IDE's Command Window you can do a
? newid("xy") && the function must be "in scope",
&& i.e in your case the database that contains the "Stored
&& Procedure" must have been opened in advance
&& or you store the function result in a variable
Local lnNextID
lnNextID = newid("xy")
Or you can use it in an SQL SELECT when you have a From alias
CREATE CURSOR placebo (col1 Int)
INSERT INTO placebo VALUES (8)
Select newid("xy") FROM placebo
I create two functions that worked well as a stand alone functions.
But when I try to run one of them inside the second one I got an error:
'SQL compilation error: Unsupported subquery type cannot be evaluated'
Can you advise?
Adding code bellow:
CASE
WHEN (regexp_substr(ARGUMENTS_JSON,'drives_removed":\\[]') = 'drives_removed":[]') THEN **priceperitem(1998, returnitem_add_item(ARGUMENTS_JSON))**
WHEN (regexp_substr(ARGUMENTS_JSON,'drives_added":\\[\\]') = 'drives_added":[]') THEN 1
WHEN (regexp_substr(ARGUMENTS_JSON,'from_flavor') = 'from_flavor') THEN 1
WHEN (regexp_substr(ARGUMENTS_JSON,'{}') = '{}') THEN 1
ELSE 'Other'
END as Price_List,
The problem happened when with function 'priceperitem'
If I replace returnitem_add_item with a string then it will work fine.
Function 1 : priceperitem get customer number and a item return pricing per the item from customer pricing list
Function 2 : returnitem_add_item parsing string and return a string
As an alternative, you may try processing udf within a udf in the following way :
create function x()
returns integer
as
$$
select 1+2
$$
;
set q=x();
create function pi_udf(q integer)
returns integer
as
$$
select q*3
$$
;
select pi_udf($q);
If this does not work out as well, the issue might be data specific. Try executing the function with one record, and then add more records to see the difference in the behavior. There are certain limitations on using SQL UDF's in Snowflake and hence the 'Unsupported Subquery' Error.
I'm trying to implement a routine for replacing some invalid characters in a BW transformation. But I keep getting a syntax error. This is my current code:
METHOD S0001_G01_R40 BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY.
-- target field: 0POSTXT
-- Note the _M class are not considered for DTP execution.
-- AMDP Breakpoints must be set in the _A class instead.
outTab = SELECT REPLACE_REGEXPR('([^[:print:]|^[\x{00C0}-\x{017F}]|[#])'
IN "SGTXT" WITH '' OCCURRENCE ALL ) AS "/BI0/OIPOSTXT"
FROM :inTab;
errorTab = SELECT '' AS ERROR_TEXT,
'' AS SQL__PROCEDURE__SOURCE__RECORD FROM DUMMY
WHERE DUMMY <> 'X';
ENDMETHOD.
I keep getting the following error:
SQLSCRIPT message: return type mismatch: Procedure
/BIC/QCW72C4IJDC8JAFRICAU_M=>S0001_G01_R40: OUTTAB[ /BI0/OIPOSTXT:NVARCHAR(5000) ]
!= expected result [ POSTXT:NVARCHAR(60) RECORD:NVARCHAR(56)
SQL__PROCEDURE__SOURCE__RECORD:NVARCHAR(56) ]
Can anyone give me an idea of what I'm doing wrong here?
For those wondering how to correct this problem, here is the solution.
Everything is in the error message:
OUTTAB[ /BI0/OIPOSTXT:NVARCHAR(5000) ]
!= expected result [ POSTXT:NVARCHAR(60) RECORD:NVARCHAR(56)
SQL__PROCEDURE__SOURCE__RECORD:NVARCHAR(56) ]
It means the result table OutTab contains only one field (/BI0/OIPOSTXT) and so is different by the OutTab expected which should contain 3 fields POSTXT, RECORD and SQL__PROCEDURE__SOURCE__RECORD.
The expected structure can usually be seen on top of the public section:
types:
begin of TN_S_IN_S0001_G01_R1_1,
POSTXT type C length 60,
RECORD type C length 56,
SQL__PROCEDURE__SOURCE__RECORD type C length 56,
end of TN_S_IN_S0001_G01_R1_1 .
So the correct syntax would be:
outTab =
SELECT CAST(REPLACE_REGEXPR('([^[:print:]|^[\x{00C0}-\x{017F}]|[#])' IN "SGTXT" WITH '' OCCURRENCE ALL) AS NVARCHAR(60)) AS "POSTXT"
,"RECORD" AS "RECORD"
,SQL__PROCEDURE__SOURCE__RECORD AS "SQL__PROCEDURE__SOURCE__RECORD"
FROM :inTab;
Regards,
Jean-Guillaume
You might want to enclose the regex expression in a CAST( ... AS NVARCHAR(60)) to ensure that the resulting record structure matches the expected return type.
I'm trying to retrieve some data from a postgresql database using psycogp2, and either exclude a variable number of rows or exclude none.
The code I have so far is:
def db_query(variables):
cursor.execute('SELECT * '
'FROM database.table '
'WHERE id NOT IN (%s)', (variables,))
This does partially work. E.g. If I call:
db_query('593')
It works. The same for any other single value. However, I cannot seem to get it to work when I enter more than one variable, eg:
db_query('593, 595')
I get the error:
psycopg2.DataError: invalid input syntax for integer: "593, 595"
I'm not sure how to enter the query correctly or amend the SQL query. Any help appreciated.
Thanks
Pass a tuple as it is adapted to a record:
query = """
select *
from database.table
where id not in %s
"""
var1 = 593
argument = (var1,)
print(cursor.mogrify(query, (argument,)).decode('utf8'))
#cursor.execute(query, (argument,))
Output:
select *
from database.table
where id not in (593)
From Java I am doing the following query on DB2:
SELECT * FROM PRV_PRE_ACTIVATION WHERE TRANSACTION_ID = ?
The field TRANSACTION_ID is a VARCHAR of length 32. I set the parameter in the preparedStatement using the setString method.
I get the error:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-270, SQLSTATE=42997, SQLERRMC=63, DRIVER=3.59.81
at com.ibm.db2.jcc.am.dd.a(dd.java:676)
at com.ibm.db2.jcc.am.dd.a(dd.java:60)
at com.ibm.db2.jcc.am.dd.a(dd.java:127)
at com.ibm.db2.jcc.am.bn.c(bn.java:2546)
at com.ibm.db2.jcc.am.bn.d(bn.java:2534)
at com.ibm.db2.jcc.am.bn.a(bn.java:2026)
at com.ibm.db2.jcc.t4.cb.g(cb.java:140)
at com.ibm.db2.jcc.t4.cb.a(cb.java:40)
at com.ibm.db2.jcc.t4.q.a(q.java:32)
at com.ibm.db2.jcc.t4.rb.i(rb.java:135)
at com.ibm.db2.jcc.am.bn.gb(bn.java:1997)
at com.ibm.db2.jcc.am.cn.pc(cn.java:3009)
at com.ibm.db2.jcc.am.cn.b(cn.java:3786)
at com.ibm.db2.jcc.am.cn.bc(cn.java:678)
at com.ibm.db2.jcc.am.cn.executeQuery(cn.java:652)
Where the sqstate means "Capability is not supported by this version of the DB2 application requester, DB2 application server, or the combination of the two." But I don't use any strange functionality.
I have tried using an squ client the query:
SELECT * FROM PRV_PRE_ACTIVATION where transaction_id='A'
And it goes ok.
What is the cause of the problem?
UPDATE: The code where the statement is prepared:
s = con.prepareStatement(sSQL,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
Try changing to a specified list of columns in the select list -- my guess is you have a user defined column type (or some other type) which is not supported by your driver. For example, does the statement
SELECT TRANSACTION_ID FROM PRV_PRE_ACTIVATION WHERE TRANSACTION_ID = ?
work? If so then start adding columns in and you will find the problem column.
I've came across this problem lately, and after some searching on web, I've came across this link:
DB2 SQL error: SQLCODE: -270, SQLSTATE: 42997, SQLERRMC: 63
, which specifies this:
A column with a LOB type, distinct type on a LOB type, or
structured type cannot be specified in the select-list of an
insensitive scrollable cursor.
With help from an colleague, we came to this conclusion:
1, Q: When will you get this "SQLCODE=-204, SQLSTATE=42704" exception?
A: When a scrollable PreparedStatement is prepared & executed, yet there are [B|C]LOB fields exist in the select list. e.g.:
String strQuery = "SELECT NUMBER_FIELD, CHAR_FIELD, CLOB_FIELD FROM TABLE_NAME WHERE CONDITION IS TRUE;"
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, REsultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(strQuery); //and this exception will be thrown here
2, Q: So what's the solution if we want to get rid of it when [B|C]LOB fields are queried?
A: Try to use ResultSet.TYPE_FORWARD_ONLY while creating the query statement.e.g.:
stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
Or simply try this one:
stmt = conn.createStatement();
Note that the same rules apply to conn.prepareStatement() too. You may refer to Java API doc for more information.