Error message when try to run a function in function - sql

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.

Related

Access - "Data type mismatch in criteria expression" with VBA function

I get error Data type mismatch in criteria expression when running this query.
See below what I tried. Question is how can I investigate further to find the error?
SELECT qCalls.Senso, qCalls.Data, qCalls.Ora, qCalls.NumeroPulito, qCalls.Durata, qContactsOutlookPerCallsUNION.Azienda, IIf(Count([NOME])=1,First([NOME]),"**nomi multipli**") AS Nome2
FROM qCalls INNER JOIN qContactsOutlookPerCallsUNION ON qCalls.NumeroPulito = qContactsOutlookPerCallsUNION.Numero
GROUP BY qCalls.Senso, qCalls.Data, qCalls.Ora, qCalls.NumeroPulito, qCalls.Durata, qContactsOutlookPerCallsUNION.Azienda
ORDER BY qCalls.Data DESC;
Both qCalls and qContactsOutlookPerCallsUNION run correctly when called separately.
There is no criteria expression (= WHERE clause, as I understand it) in my SQL. I then think the data type issue is on the INNER JOIN part but:
qCalls.NumeroPulito is a string, comes from: CStr(Replace([Number],"+39","")) AS NumeroPulito
qContactsOutlookPerCallsUNION.Numero is a string, it comes from: IIf(IsNull([Phone]),Null,PulisciTelPerCalls([Phone])) AS Fisso where PulisciTelPerCalls() is a VBA function which returns a string
Without being too sure, I believe the error is caused by the inline if statement IIF() since it checks both conditions anyway, thus could be sending a null value to the function.
I think you should scrap the IIF and handle null values in the function.
Public Function PulisciTelPerCalls(ByVal Phone As Variant) As String
If IsNull(Phone) Then
PulisciTelPerCalls = vbNullString
Exit Function
End If
'rest of method
End Function
Then just call the method directly:
PulisciTelPerCalls([Phone]) AS Fisso
CStr on a string doesn't make sense. Try removing it and use Nz:
Replace([Number],"+39","") AS NumeroPulito
and
PulisciTelPerCalls(Nz([Phone])) AS Fisso
or
IIf(IsNull([Phone]),"",PulisciTelPerCalls([Phone])) AS Fisso

Passing Optional List argument from Django to filter with in Raw SQL

When using primitive types such as Integer, I can without any problems do a query like this:
with connection.cursor() as cursor:
cursor.execute(sql='''SELECT count(*) FROM account
WHERE %(pk)s ISNULL OR id %(pk)s''', params={'pk': 1})
Which would either return row with id = 1 or it would return all rows if pk parameter was equal to None.
However, when trying to use similar approach to pass a list/tuple of IDs, I always produce a SQL syntax error when passing empty/None tuple, e.g. trying:
with connection.cursor() as cursor:
cursor.execute(sql='''SELECT count(*) FROM account
WHERE %(ids)s ISNULL OR id IN %(ids)s''', params={'ids': (1,2,3)})
works, but passing () produces SQL syntax error:
psycopg2.ProgrammingError: syntax error at or near ")"
LINE 1: SELECT count(*) FROM account WHERE () ISNULL OR id IN ()
Or if I pass None I get:
django.db.utils.ProgrammingError: syntax error at or near "NULL"
LINE 1: ...LECT count(*) FROM account WHERE NULL ISNULL OR id IN NULL
I tried putting the argument in SQL in () - (%(ids)s) - but that always breaks one or the other condition. I also tried playing around with pg_typeof or casting the argument, but with no results.
Notes:
the actual SQL is much more complex, this one here is a simplification for illustrative purposes
as a last resort - I could alter the SQL in Python based on the argument, but I really wanted to avoid that.)
At first I had an idea of using just 1 argument, but replacing it with a dummy value [-1] and then using it like
cursor.execute(sql='''SELECT ... WHERE -1 = any(%(ids)s) OR id = ANY(%(ids)s)''', params={'ids': ids if ids else [-1]})
but this did a Full table scan for non empty lists, which was unfortunate, so a no go.
Then I thought I could do a little preprocessing in python and send 2 arguments instead of just the single list- the actual list and an empty list boolean indicator. That is
cursor.execute(sql='''SELECT ... WHERE %(empty_ids)s = TRUE OR id = ANY(%(ids)s)''', params={'empty_ids': not ids, 'ids': ids})
Not the most elegant solution, but it performs quite well (Index scan for non empty list, Full table scan for empty list - but that returns the whole table anyway, so it's ok)
And finally I came up with the simplest solution and quite elegant:
cursor.execute(sql='''SELECT ... WHERE '{}' = %(ids)s OR id = ANY(%(ids)s)''', params={'ids': ids})
This one also performs Index scan for non empty lists, so it's quite fast.
From the psycopg2 docs:
Note You can use a Python list as the argument of the IN operator using the PostgreSQL ANY operator.
ids = [10, 20, 30]
cur.execute("SELECT * FROM data WHERE id = ANY(%s);", (ids,))
Furthermore ANY can also work with empty lists, whereas IN () is a SQL syntax error.

Database Table Column is taken as String Value in Oracle Function in JSP

Select decrypt(PRODUCT_NUMBER,'123456789') as PRODUCT_NUMBER FROM Test
PRODUCT_NUMBER is a column in Test Table and contains Encrypted data Decrypt() is a function created and working fine.
When i run this Sql on Oracle SQL Developer it gives correct Result but when i run the same on JSP it gives me error on Function.
In JSP i call this by:
String sql = "Select decrypt(PRODUCT_NUMBER,'123456789') as PRODUCT_NUMBER FROM Test";
rs = conn.executeQuery(sql);
I think it takes PRODUCT_NUMBER as String ('PRODUCT_NUMBER') and Not as Column Name so it gives error.
java.sql.SQLException: ORA-01465: invalid hex number
This is the Decrypt Function
create or replace FUNCTION decrypt(p_raw IN RAW, p_key IN VARCHAR2) RETURN VARCHAR2 IS
v_retval RAW(255);
p_key2 RAW(255);
BEGIN
p_key2 := utl_raw.cast_to_raw(p_key);
dbms_obfuscation_toolkit.DES3Decrypt
(
input => p_raw,
key => p_key2,
which => 1,
decrypted_data => v_retval
);
RETURN RTRIM(utl_raw.cast_to_varchar2(v_retval), CHR(0));
END decrypt;
Solved!!
Query and Function both work perfect.
Actually My Co Developer had pointed the Connection to another replica instance of the DB that contained -1 in some columns so that's why it was giving error.
I reverted that and query worked like a charm.
Thanks for your time Everyone:)

How do I extract a value from a Linq IQueryable object?

I am new to Linq and have been stumped for several days. I have searched this and several other boards to find the answer but cannot. I have a Linq query that is returning 1 value of int.
Public Function myV()
Dim MR As New MainEntities()
Dim mV = From AspNetUsers In MR.AspNetUsers
Where Context.User.Identity.Name() = AspNetUsers.Email.ToString Select AspNetUsers.VB
Return mV
End Function
If myV = 1 Then
perform other code
End If
But when I try to compare to an Int it says the object cannot be compared. I have tried to convert the IQueryable(of Interger) to Int and cannot. How do I get to the Interger value in the IQueryable object?
The LINQ statement returns an IEnumerable, which is like an array in that it can hold multiple values, even it only happens to have one value in it.
The best way to return a single value is .First(), or .Single() if you want to throw an exception if more than one value exists. (Which one you choose depends on your context.)
Public Function myV()
Dim MR As New MainEntities()
Dim mV = From AspNetUsers In MR.AspNetUsers
Where Context.User.Identity.Name() = AspNetUsers.Email.ToString Select AspNetUsers.VB.First()
Return mV
End Function
Because mV is an IQueryable, you can consider it as a type of list or an array. So you need to get the first value:
If myV.First() = 1 Then
'...
End If
Or more likely you want to do that inside the mV function:
Dim mV = From AspNetUsers In MR.AspNetUsers
Where Context.User.Identity.Name() = AspNetUsers.Email.ToString
Select AspNetUsers.VB
Return mV.First()
You misunderstood the query. Your LINQ executes a SQL Statement that is the follows:
SELECT AspNetUsers.VB
FROM AspNetUsers
WHERE ApsNetUsers.Email = "here the name"
Therefore the query does not return only one VB but a table consisting of one column and multiple rows.
In order to retrieve the first value you have to call .First()
If myV.First() = 1 Then [...]

Firebird " Column does not belong to referenced table "

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.