Teradata INSTR in UNIX SHELL - sh

INSTR and SUBSTRING are not working in SHELL SCRIPT
Hi
Iam Using INSTR and SUBSTRING in UNIX shell script. They are working in Teradata sql assistant but they both are not working in UNIX SHELL SCRIPT.
I changed SUBSTRING to SUBSTR and it worked. But i still have problem with INSTR. Can any one help me out.
Example :
select
case when SubRegion like '%REGION%' then SubRegion else SubRegion || ' '
|| 'REGION' end REGION_NAME,
SUBSTR(nodes FROM instr(nodes,'-',1,1)+1 for instr(nodes,'-',1,1)-1) AS node,
SgSpeed,
SgUtil,
PortCount,
CAST(WeekEndingDate as DATE) WEEKENDINGDATE
FROM RNL_VIEWS.WT_CmtsSgUtil
WHERE instr(nodes,'-') > 0
and WeekEndingDate = '2014-12-06'
ERROR:
SUBSTR(nodes FROM instr(nodes,'-',1,1)+1 for instr(nodes,'-',1,1)-1) AS n
ode,
$
*** Failure 3706 Syntax error: expected something between the word 'nodes'
and the 'FROM' keyword.
Statement# 1, Info =582
*** Total elapsed time was 1 second.
Thanks
Naveen

There are two variations of substring in Teradata:
SUBSTRING(str FROM startpos FOR length) -- Standard SQL
SUBSTR(str, startpos, length) -- Teradata SQL
SUBSTR(str FROM startpos FOR length) doesn't exist, but the ODBC driver might rewrite ODBC-style SUBSTRING(str, startpos, length). This is also done for other ODBC-functions like LEFT or MONTH. Whenever you try to submit such a query using CLI/.NET/JDBC it will fail.
To disable this rewrite you to need to check the 'Disable Parsing' in the ODBC driver's options.
Regarding INSTR, this is included since TD14 and should not cause any error.

Related

what does caret do in postgresql?

I'm playing hackthebox machine's and current one has a postgresql db in place. The query breaks with ' and appeas as follows:
ERROR: unterminated quoted string at or near "'" LINE 1: Select * from
cars where name ilike '%test'%' ^
I understand that % is being used to search within the query string for the characters provided but, What is ^ used for?
Bold highlights my test query
All my searches yielded resulst regarding regexes and caret signaling the start of the string. Plus other result about using cli or something like that.
Can anybody tell me what is it doing at the end of the query?
Your are looking for the use of the caret specifically within error messages.
If I run this query:
psql -c " Select * from cars where name ilike '%test'%'"
This is what I get, preserving line breaks and spaces:
ERROR: unterminated quoted string at or near "'"
LINE 1: Select * from cars where name ilike '%test'%'
^
The caret points to where on the previous line the error occurred. In this case, that is where the opening quote mark that never got closed was located.
If you are using a tool which malformats your error messages, you should consider changing to one that does not or otherwise figuring out how to fix it.

How to get output of a sql with additional special characters

Long story...
I am trying to geenrate a crosstab query dynamically and run it as a psql script..
To achieve this, I want the last line of the sql to generated and appended to the top portion of the sql.
The last line of the sql is like this.... "as final_result(symbol character varying,"431" numeric,"432" numeric,"433" numeric);"
Of which, the "431", "432" etc are to be generated dynamically as these are the pivot columns and they change from time to time...
So I wrote a query to output the text as follows....
psql -c "select distinct '"'||runweek||'" numeric ,' from calendar where runweek between current_runweek()-2 and current_runweek() order by 1;" -U USER -d DBNAME > /tmp/gengen.lst
While the sql provides the output, when I run it as a script, because of the special characters (', "", ) it fails.
How should I get it working? My plan was then loop through the "lst" file and build the pivot string, and append that to the top portion of the sql and execute the script... (New to postgres, does not know , dynamic sql generation and execution etc.. but I am comfortable with UNIX scripting..)
If I could somehow get the output as
("431" numeric, "432" numeric....etc) in a single step, if there is a recommendation to achieve this, it will be greatly appreciated.....
Since you're using double quotes around the argument, double quotes inside the argument must be escaped with a backslash:
psql -c "select distinct '\"'||runweek||'\" numeric ,' from calendar where runweek between current_runweek()-2 and current_runweek() order by 1;"
Heredoc can also be used instead of -c. It accepts multi-line formatting so that makes the whole thing more readable.
(psql [arguments] <<EOF
select distinct '"'||runweek||'" numeric ,'
from calendar
where runweek between current_runweek()-2 and current_runweek()
order by 1;
EOF
) > output
By using quote_ident which is specifically meant to produce a quoted identifier from a text value, you don't even need to add the double quotes. The query could be like:
select string_agg( quote_ident(runweek::text), ',' order by runweek)
from calendar
where runweek between current_runweek()-2 and current_runweek();
which also solves the problem that your original query has a stray ',' at the end, whereas this form does not.

How to execute a db2 query with a where condition using runqry command in CL/400

I was trying to execute a IBM DB2 query using runqry command of CLLE, but was unable to do it as it contained a where condition and I was unable to define a host variable in the runqry command. Can this be done by using the runqry command without using qryslt.
Please help me out.
RUNQRY does not support variables.
You can define variables in the Query/400 query, but you must use the Start Query Management Query (STRQMQRY) command to run the query.
Be sure to specify:
Allow information from QRYDFN . ALWQRYDFN *YES`
Here's an IBM document that shows how to do it.
Select Records
Type comparisons, press Enter. Specify OR to start each new group.
Tests: EQ, NE, LE, GE, LT, GT, RANGE, LIST, LIKE, IS, ISNOT...
AND/OR Field Test Value (Field, Number, 'Characters', or ...)
GLCOMP EQ :COMPANY
AND GLBRAN EQ :BRANCH
AND GLACC EQ :ACCOUNT
-----------------------------------------------------------------------
STRQMQRY QMQRY(library/qry-name) ALWQRYDFN(*YES) +
QMFORM(*QMQRY) SETVAR((COMPANY 1) (BRANCH 1) (ACCOUNT 12000))

how to find max date and hour everyday by using hive query

I am getting error as org.apache.hive.service.cli.HiveSQLException:
Error while compiling statement: FAILED: ParseException line 1:168 cannot recognize input near 'select' 'max' '(' in expression specification while using max(date) and max(sum_hour)
If I interpret correctly, you can do:
select max(datecol)
from t
group by year(datecol), month(datecol), day(datecol);
date is a reserved word.
Use `date` or even better, rename your column

Raise error when date is not valid

What I'm trying to do is to raise out of range error in case of dates outside of the supported range like what typecasting does.
I'm using PostgreSQL-9.1.6 on CentOS. The issue is below...
postgres=# select to_date('20130229','yyyymmdd');
to_date
------------
2013-03-01
(1 row)
But the output I want to see is:
postgres=# select '20130229'::date;
ERROR: date/time field value out of range: "20130229"
Surfing the web I found an informative page. So I did adding IS_VALID_JULIAN to the function body of to_date, adding the four lines marked + below to formatting.c:
Datum
to_date(PG_FUNCTION_ARGS)
{
text *date_txt = PG_GETARG_TEXT_P(0);
text *fmt = PG_GETARG_TEXT_P(1);
DateADT result;
struct pg_tm tm;
fsec_t fsec;
do_to_timestamp(date_txt, fmt, &tm, &fsec);
+ if (!IS_VALID_JULIAN(tm.tm_year, tm.tm_mon, tm.tm_mday))
+ ereport(ERROR,
+ (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+ errmsg("date out of range: \"%s\"",text_to_cstring(date_txt))));
result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - POSTGRES_EPOCH_JDATE;
PG_RETURN_DATEADT(result);
}
Then I rebuilt PostgreSQL:
pg_ctl -m fast stop # 1. stopping pgsql
vi src/backend/utils/adt/formatting.c # 2. using the version above
rm -rf /usr/local/pgsql/* # 3. getting rid of all bin files
./configure --prefix=/usr/local/pgsql
--enable-nls --with-perl --with-libxml
--with-pam --with-openssl
make && make install # 4. rebuilding source
pg_ctl start # 5. starting the engine
My bin directory info is below.
[/home/postgres]echo $PATH
/usr/lib64/qt-3.3/bin:
/usr/local/bin:
/bin:
/usr/bin:
/usr/local/sbin:
/usr/sbin:
/sbin:
/home/postgres/bin:
/usr/bin:
/usr/local/pgsql/bin:
/usr/local/pgpool/bin:
/usr/local/pgtop/bin/pg_top:
[/home/postgres]which pg_ctl
/usr/local/pgsql/bin/pg_ctl
[/home/postgres]which postgres
/usr/local/pgsql/bin/postgres
[/usr/local/bin]which psql
/usr/local/pgsql/bin/psql
But upon checking to_date again, the result remained the same.
postgres=# select to_date('20130229','yyyymmdd');
to_date
------------
2013-03-01
(1 row)
Is there anything I missed?
You can write your own to_date() function, but you have to call it with its schema-qualified name. (I used the schema "public", but there's nothing special about that.)
create or replace function public.to_date(any_date text, format_string text)
returns date as
$$
select to_date((any_date::date)::text, format_string);
$$
language sql
Using the bare function name executes the native to_date() function.
select to_date('20130229', 'yyyymmdd');
2013-03-01
Using the schema-qualified name executes the user-defined function.
select public.to_date('20130229', 'yyyymmdd');
ERROR: date/time field value out of range: "20130229"
SQL state: 22008
I know that's not quite what you're looking for. But . . .
It's simpler than rebuilding PostgreSQL from source.
Fixing up your existing SQL and PLPGSQL source code is a simple search-and-replace with a streaming editor. I'm pretty sure that can't go wrong, as long as you really want every use of the native to_date() to be public.to_date().
The native to_date() function will still work as designed. Extensions and other code might rely on its somewhat peculiar behavior. Think hard and long before you change the behavior of native functions.
New SQL and PLPGSQL would need to be reviewed, though. I wouldn't expect developers to remember to write public.to_date() every time. If you use version control, you might be able to write a precommit hook to make sure only public.to_date() is used.
The native to_date() function has behavior I don't see documented. Not only can you call it with February 29, you can call it with February 345, or February 9999.
select to_date('201302345', 'yyyymmdd');
2014-01-11
select to_date('2013029999', 'yyyymmdd');
2040-06-17