Cannot call methods on nvarchar(max) or varchar(max) - tsql

select
EmailAttachmentFilename,
IsNull(EmailAttachmentFilename,'').Replace('*','%') as EmailAttachmentFilename2
from dbo.MyTable1
gives the following error:
Cannot call methods on nvarchar(max).
I also added the Convert function, but that didn't solve the issue.

This is what happens when you have been doing C# or Python for a long time, then switch back to SQL. Replace is not a method in T-SQL, it is a function.
Here is the correct use of the Replace function.
select
EmailAttachmentFilename,
Replace(IsNull(EmailAttachmentFilename,''),'*','%') as EmailAttachmentFilename3
from dbo.Ch_BizTalk_IncomingEmail_Routing
from dbo.MyTable1
When I did this, I got a much more clear error:
select
EmailAttachmentFilename,
EmailAttachmentFilename.Replace('*','%') as EmailAttachmentFilename4
from dbo.MyTable1
Resulting error:
Incorrect syntax near 'Replace'.
However, when using the IsNull function, the error is rather obfuscated.

Related

Postgres convert integer into text

I have a question. I'm using a Postgrs database, and my problem is that I need to use the ints as text. I have the following solution:
CREATE FUNCTION pg_catalog.text(integer) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int4out($1));';
CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.text(integer) AS IMPLICIT;
COMMENT ON FUNCTION pg_catalog.text(integer) IS 'convert integer to text';
I had been reading that this solution is not correct, it can cause some problems in the future. So I had been doing a research through the internet and I saw some people only use CAST, but just to convert a specific int, i.e., https://dba.stackexchange.com/questions/82511/how-to-enable-implicit-casts-in-postgresql-9-2
The danger with creating an implicit cast like that is that it destabilizes the carefully balanced type system in PostgreSQL; after that, some innocent invocations of overloaded functions will stop working because due to the cast, there are suddenly too many candidate functions to make a unique choice.
It is much better to use an explicit cast:
CAST (intcol AS text)
That is standard SQL and should work everywhere.

Postgres function update column ambiguous

I create a postgres function like this:
CREATE OR REPLACE FUNCTION delete_annotation_f(
IN cmtid uuid)
RETURNS bool AS $$
DECLARE
pid uuid;
cmt_cnt int4;
BEGIN
SELECT get_comment_cnt_f(cmtid) INTO cmt_cnt;
UPDATE detail_t SET ann_cmt_cnt=ann_cmt_cnt - cmt_cnt;
RETURN TRUE;
END
$$
LANGUAGE plpgsql;
But when I run this function I get this error:
ERROR: column reference "cmt_cnt" is ambiguous
LINE 1: ...detail_t SET ann_cmt_cnt=ann_cmt_cnt-cmt_cnt WH...
I find this link On Inset: column reference "score" is ambiguous but it could not help me solve the problem. Anyone have solutions?
You are using a variable that have the same name of a column. The query parser could not decide which it must chose, change your variable name then the ambiguity will vanish.
https://www.postgresql.org/docs/current/static/plpgsql-implementation.html
By default, PL/pgSQL will report an error if a name in a SQL statement
could refer to either a variable or a table column. You can fix such a
problem by renaming the variable or column, or by qualifying the
ambiguous reference, or by telling PL/pgSQL which interpretation to
prefer. The simplest solution is to rename the variable or column. A common
coding rule is to use a different naming convention for PL/pgSQL
variables than you use for column names. For example, if you
consistently name function variables v_something while none of your
column names start with v_, no conflicts will occur.
and further:
You can also set the behavior on a function-by-function basis, by
inserting one of these special commands at the start of the function
text:
#variable_conflict error
#variable_conflict use_variable
#variable_conflict use_column

XMLQUERY() WITHIN XMLATTRIBUTES()

I am doing some basic tasks using, sql/xml. I am currently working on an error message that I get when trying to compute a XMLQUERY() within a XMLATTRIBUTES() function. (See code below)
SELECT XMLELEMENT(NAME "Nodename",
XMLATTRIBUTES(XMLQUERY('$t//Element/text()' PASSING Info AS "t") AS "hello"))
FROM Kurs
The error message that I get, says that there is no qualified routine that can run the function. I cant copy-paste the error message because its in Swedish, but this should be enough.
Also this might help: SQLCODE=-440, SQLSTATE=42884, DRIVER=4.18.60
So my question is (I have been looking for the answer), why doesn't this work? I will always get a value from that XMLQUERY, and it should simply translate into a value and used by XMLATTRIBUTES()
Any documentation, or link, is welcomed as well!
Thank you in advance!
The scalar function XMLQUERY returns an XML value. The function XMLATTRIBUTES expects an expression that returns a value of any type, but XML and some other types.
Thus, the functions are not compatible the way you are using them. DB2 cannot find a routine with that function signature. It results in that error -440.
How about wrapping a CAST/XMLCAST around it...?

Errors with an easy PL/pgSQL Function

I'm trying to write my first PL/pgSQL function. For right now it is simply supposed to return the number of characters in a value that is passed to it.
CREATE OR REPLACE FUNCTION public.cents(money)
RETURNS int
LANGUAGE plpgsql
LEAKPROOF
AS $function$
DECLARE
new_price money;
size int;
BEGIN
size := char_length(money);
RETURN size;
END;
$function$;
When I try to test with $66.66 I get one error:
select cents($66.66);
ERROR: syntax error at or near ".66"
LINE 1: select cents($66.66);
^
And if I use $66 I get a different error:
select cents($66);
ERROR: there is no parameter $66
LINE 1: select cents($66);
^
Using just the integer 66 gives me a third error:
select cents(66);
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
What am I doing wrong here?
Are you sure you want to use the data type money? Consider:
PostgreSQL: Which Datatype should be used for Currency?
If you need the type money, be sure to understand the role of locale settings for this type. Read the manual.
You can't enter literals without single quotes (like numeric constants) - unless you cast them, which would be inefficient. But that's not the only error. Your function would work like this:
CREATE OR REPLACE FUNCTION public.cents(_my_money_parameter money)
RETURNS int AS
$func$
BEGIN
RETURN char_length(_my_money_parameter::text);
END
$func$ LANGUAGE plpgsql LEAKPROOF;
Call:
SELECT public.cents(money '66.66');
SELECT public.cents('66.66'::money);
SELECT public.cents(66.66::money);
The 1st call variant is the most efficient, but it depends on locale settings. The dot in my example is interpreted as thousands separator and ignored (not as decimal point) in some locales.
Notes
You treat money like a parameter name in the function body, but it's just the data type. If you want to use parameter names, you have to declare them like demonstrated. Or refer to parameters with positional references: $1, $2 etc.
char_length() expects a character data type, you cannot use it for data type money without casting. Just length() is equivalent.
If you include the dollar sign, you need single quotes for the string literal: '$66.66' - and the format must match your locale setting to work for money.
If you just supply the numeric constant 66, Postgres won't find the function with a money parameter due to the rules of function type resolution. Details:
Is there a way to disable function overloading in Postgres
Start by reading the chapter Constants in the manual.
Continue with the page on CREATE FUNCTION.
You need to put single-quotes around your input:
SELECT cents('$66.66');
If your settings don't allow this (still throw an error) you can try casting:
SELECT cents('66.66'::float8::numeric::money);
Be sure to reference the docs as they provide a good overview:
https://www.postgresql.org/docs/current/static/datatype-money.html

String passed into cursor.callproc becomes unknown (psycopg2, python 2.7, postgres 9.3)

For some reason, passing a string from Python into a Postgres function and calling it using a psycopg2 cursor causes the function to be unrecognized because the argument is unknown.
The function is very simple like so:
CREATE OR REPLACE FUNCTION text_test (some_text text)
RETURNS void AS $$
BEGIN
END;
$$ LANGUAGE plpgsql;
On the python side, I have:
cursor.callproc("text_test", ("test",))
And I get the following error:
psycopg2.ProgrammingError: function text_test(unknown) does not exist
LINE 1: SELECT * FROM text_test('test')
^
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Why does this only happen with strings and what do I need to do to have a function successfully accept a string? For some reason numeric data types are unaffected by this problem.
This happens because there is no way to cast the string to the "correct" text type. Is it a char(N)? A varchar(N)? A text?
Unfortunately .callproc() doesn't provide an easy way to specify the argument types but you can always use .execute() casting the arguments explicitly and everything works:
curs.execute("SELECT * FROM text_test(%s::text)", ("test",))
You could also make a list with the parameters you need to send:
param_list = ["test"]
curs.callproc(proc_name, param_list)
Here is a good answer about it:
python + psycopg2 = unknown types?