Oracle Setting Up a Globalization Support Environment - sql

We want to set this SET NUMFORMAT 99999999999999999.00 at the user/schema level, for all sessions. Currently ,when set this command , it is getting applicable for that session only. Can we do this globally , so that when ever we open the connection , this works >

SET NUMFORMAT is a SQL*Plus command. In general, it is a client-side setting to display the number.
You could always store the SQL*Plus settings in login.sql and glogin.sql. Whenever SQL*Plus starts up, it looks for a file named glogin.sql under the directory $ORACLE_HOME/sqlplus/admin. If such a file is found, it is read and the containing statements are executed. Additionally, after reading glogin.sql, sql*plus also looks for a file named login.sql in the directory from where SQL*Plus was and in the directory that the environment variable SQLPATH points to and reads it and executes it. Settings from the login.sql take precedence over settings from glogin.sql.
If you are just displaying the number, and want it to be displayed in desired format, then use TO_CHAR at individual SQL statement level.
For example,
SQL> select to_char(123.456,'999.9') VALUE from dual
2 /
VALUE
------
123.5
Bottomline, this is a SQL*Plus command, not an Oracle SQL or PL/SQL command. This will only affect how the data is displayed from SQL*Plus, not from other programs that access the database. There should be something similar in whatever you are using to display your data instead of SQL*Plus.

Related

A fatal scripting error occurred. Variable is not defined

When I run this query in SQLCMD mode in SSMS 2017 and SQL Server DB. It works fine.
--SQLCMD mode
--DECLARE Global variables
:SETVAR daysBack -1
SELECT $(daysBack)
Result: -1
If I run only 1 line
SELECT $(daysBack)
in the same window on the same connection, or in another tab. I am getting error
fatal scripting error occurred.
Variable daysBack is not defined.
Why I am getting error?
and how can I make my varibale Global, for example like
SELECT '$(COMPUTERNAME)'
I don't think you can. SQLCMD variables are a client tool trick, they don't really exist as a SQL Server concept.
The connection and server are not aware of their existence and the system doesn't persist knowledge of variables used in previous batches when you submit a new batch.
From sqlcmd - Use with Scripting Variables:
If more than one type of variable has the same name, the variable with the highest precedence is used.
System level environmental variables
User level environmental variables
Command shell (SET X=Y) set at command prompt before starting sqlcmd
sqlcmd-v X=Y
:Setvar X Y
Of these, the first three are effectively taken from when a particular process was launched, unless that process has specific tooling to allow environmental variable to be edited. Neither SSMS nor SQLCMD has such functionality so you cannot create a variable in these categories once the tool is already running.
The fourth is SQLCMD specific and has no equivalent in SSMS. Only the last one (using :setvar) remains, and this does not create a "global" variable (which are in fact just the environmental variables and the SQLCMD built-in variables).

How to run an oracle query in linux with a table like output

I'm totally new in running sql queries in linux and I'm having a hard time dealing with it's output.
So I managed to access my database in oracle in linux and trying to run a simple query right now:
SELECT IN_01, OUT_BD_01 FROM TRANSLATION_ROW WHERE IN_01 = 'LS3K5GB';
I'm expecting it to be in a table-like output but instead i got this:
Any Help would be much appreciated. By the way, I'm accessing my Oracle server through putty. I don't know if that helps in anything.
--forgot to mention that I also use sqlplus. Don't know if that would make any difference
Thanks in advance.
Welcome to the weird and wonderful world of Oracle.
Viewing large amounts of data (especially "wide" data) through sqlplus has always been less than pretty. Even back in the 1990s Oracle rival Ingres had a rather nice isql which made a much better fist of this, although the flipside of that was using isql to spool to a data file (no headers and trimmings, etc) was slightly harder. I think the rather primitive nature of SQLPLus is why TOAD/SQL*Developer etc have become popular.
To make the output easier to read, you need to learn the basics of sqlplus formatting, in particular SET LINES, PAGES, TRIMSPOOL, TAB, and the COLUMN formatting command.
Use COLUMN to control the formatting of each column.
One possible option is to use SET MARKUP and spool to a file, which formats the output as HTML table, but then you need a HTML viewer/browser to view the results.
On PuTTY your options are limited, but if you have xterm and can invoke the browser on Linux, you might find something like a shell script:
#!/bin/bash
sqlplus un/pw #the_file
firefox the_output.html
Contents of the_file.sql:
SET MARKUP ON
spool the_output.html
SELECT * FROM user_objects;
spool off
quit
If you have a share between the Linux system where the the_output.html resides and can mount that on WIndows, you could run the query on Linux with MARKUP oN, spool to the share, then click refresh on the Browser.
Clunky, and not really what you want, but try it and see what you get.
It displays the entire column that's it.
You can format your column before running the query with the below:
e.g.: format my column to display 10 characters only
column IN_01 format a10
There are some basic configuration tricks that you should apply when using SQLplus. A basic set of parameters would be something like this:
set pagesize 50000
set linesize 135
set long 50000
set trimspool on
set tab off
All these should be placed in a login.sql file which should be in the directory you are launching sqlplus from.
This will solve your current problem, but for further reading I suggest checking out this page: Configuring sqlplus.

How does oracle (via sql/plus) determine the charset used to evaluate a sql script

I'd like to have a few details about how oracle (via sql/plus) determine the charset used to evaluate a sql script.
My database is configured like this:
select VALUE from nls_database_parameters where parameter='NLS_CHARACTERSET';
VALUE
------
WE8ISO8859P15
The problem is that I read here http://www.orafaq.com/wiki/NLS that session parameters could take precedence over database parameters.
Does it mean that database encoding is overriden by the one defined in the NLS_LANG environment variable of the user who executes the script?
Apparently, it's not possible to modify the encoding in a script via an alter session statement.
I'm asking this question since I already had a problem of corrupted characters with a production script executed by a subcontractor in India. I actually don't know if it was because he did something wrong with my file (like copy/paste in a sql gui client) or if it was because of his environment.
To summarize my actual problem, will everything be OK if
The user is configured with a charset of UTF8
My sql file is encoded in UTF8
My database is in WE8ISO8859P15
Thank's in advance for your answers.
Yes, you are correct. The Oracle Client always converts between the database characterset and the characterset of the client machine, which is determined by the NLS_LANG environment variable or the system settings.
Please note that UTF8 supports only Unicode version 3.1 and earlier. Use AL32UTF8 instead to get full Unicode support.

What does the "#" do in SQL*Plus

I found this line in a sql code:
#../../sql_scripts/create_tables.sql
What does it do? I know that ##file.sql means that file.sql is run and # could be used when we want to supply parameter values later, but here I have # followed by a filename. I know that there is a similar question but it covers only # in queries.
Here the # is not part of the SQL language. It is likely a command for the SQL interpreter which is probably Oracle SQL*Plus.
SQL*Plus has many single-character commands like # or / (which executes buffered SQL), ; which can be puzzling when you encounter them in an .sql file.
# is documented here in Oracle 9i documentation. There you will see the differences with ##.
documentation for Oracle 11g Release 2, click Next section for ## reference.
The # allows you to import another script into the sql script you're running in SQL*Plus.
For example, this executes the contents of otherscript.sql at the specified point:
PROMPT about to run other script
#otherscript.sql
PROMPT finished running other script
Another example, this inserts the contents of another file into the middle of a statement to be executed in SQL*Plus:
SELECT * FROM mytable WHERE
#predicates_for_mytable.sql
AND bla = 1;
The only condition is that # must appear at the 1st character on the line.

How do I programmatically run a complex query on an as400?

I'm new at working on an as400 and I have a query the joins across 4 tables. The query itself is fine, it runs in STRSQL and displays the results.
What I am in struggling with is getting the query to be able to run programmatically (it will eventually be run from a scheduled CL script).
I tried have creating a physical file that contains the query running it with RUNQRY, but it simply displays the query itself, not the actual result set.
Does anyone know what I am doing wrong?
UPDATE
Thanks everyone for the direction and the resources, with them I was able to reach my goal. In case it helps anyone, this is what I ended up doing (all of this was done in it's own library, ALLOCATE):
Created a source physical file (using CRTSRCPF): QSQLSRC, and created a member named SQLLEAGSEA, with the type of TXT, that contains the SQL statement.
Created another source physical file: QCLSRC, and created a member named POPLEAGSEA, with the type of CLP, that changes the current library to ALLOCATE then runs the query using RUNSQLSTM (more detail on this below). Here is the actual command:
RUNSQLSTM SRCFILE(QSQLSRC) SRCMBR(SQLLEAGSEA) COMMIT(*NONE) NAMING(*SYS)
Added the CLP to the scheduled jobs (using ADDJOBSCDE), running the following command:
CALL PGM(ALLOCATE/POPLEAGSEA)
With regard to RUNSQLSTM, my research indicated that I wasn't going to be able to use this function, because it didn't support SELECT statements. What I didn't indicate in my question was what I needed to do with the the result - I was going to be inserting the resultant data into another table (had I done that I'm sure the help could have figured that out a lot quicker). So effectively, I wasn't going to be doing an SELECT, my end result is actually an INSERT. So my SQL statement (in SQLLEAGSEA) begins with:
INSERT INTO
ALLOCATE/LEAGSEAS
SELECT
...
BLAH BLAH BLAH
...
From my research, I gather that RUNSQLSTM doesn't support SELECT because it doesn't have a mechanism to do anything with the results. Once I stopped taking baby steps and realized I needed to SELECT AND INSERT in the same statement, it solved my main problem.
Thanks again everyone!
The command is RUNSQLSTM to run a static SQL statement in a physical file member or stream file.
It is a non-interactive command so it will not execute sql statements that attempt to return a result set.
If you want more control, including the ability to run interactive statements, see the Qshell db2 utility.
For example:
QSH CMD('db2 -f /QSYS.LIB/MYLIB.LIB/MYSRCFILE.FILE/MYSQL.MBR')
Note that the db2 utility only accepts the *SQL naming convention.
QM Query
If all the SQL you need is the single complex SQL statement, and this is what it sounds like, then your best bet is to use Query Management Query (see QM Query manual here).
The results can be directed to a display, a spool file, or a physical file (ie a DB2 table). The default output when run interactively is to the screen, but when run in a (scheduled) batch job it will default to a spool file report.
You can create the QM Query interactively via WRKQMQRY, in prompted mode (much like Query/400) or in SQL mode. Or you can compile the QM Query from source, with the CRTQMQRY command.
To run your QM Query, STRQMQRY command.
RUNSQL cmd
If you are using a system that has IBM i 7.1 fully up-to-date, and has Technology Refresh 4 (TR4) installed, then you could also use the new RUNSQL command to execute a single statement. (see discussion in developerWorks)
SQL Scripting w/ RUNSQLSTM cmd
From CL you can run SQL scripts of multiple SQL statements from a source file member. There is no standard default source file name for this, but QSQLSRC is commonly used. The source member can contain multiple non-interactive SQL statements. This means you cannot use a SELECT statement (directly) since theoretically it will not know where to send the results. CL commands are even allowed if given a CL: prefix. Both SQL and CL statements should be terminated with a semicolon ;. While the SQL statements cannot display data directly to the screen, the same restriction does not apply to the scripted CL commands.
The STRQMQRY command can be embedded in the RUNSQLSTM script, by placing the prefix "CL: " in front of the command. Since STRQMQRY can direct output to the screen, a report, or an output table, this can come in very useful.
Remember that to direct your output from a SELECT query to a file you can use either the INSERT or CREATE TABLE statements.
CREATE TABLE newtbl AS
( full-select )
WITH DATA;
Or, to put the results into a table you create in your job's QTEMP library:
DECLARE GLOBAL TEMPORARY TABLE AS
( full-select )
WITH DATA;
[Note: If you create the source to be used by CRTQMQRY, you are advised to create it as CRTSRCPF yourlib/QQMQRYSRC RCDLEN(91), since the compiler will only use 79 columns of your source data (adding 12 for sequence and change date =91). However for QM Forms, which can be used to provide additional formatting, the CRTQMFORM compiler will use 81 columns so RCDLEN(93) is advised for QQMFORMSRC.]
RUNQRY is a utility that lets you execute a query that was created by another utility named WRKQRY. If you really want to process SQL statements held in a file try RUNSQLSTM. It uses a source physical file to store the statements, not a database file. The standard name for that source physical file is QQMQRYSRC. To create that file, CRTSRCPF yourlib/QQMQRYSRC. Then you can use PDM to work with that source PF. WRKMBRPDM yourlib/QQMQRYSRC. Use F6 to create a new source member. Make it source type TXT. Then use option 2 to will start an editor called SEU. Copy/paste your SQL statements into this editor. F3 to save the source. Once the source is saved, use RUNSQLSTM to execute it.
It is (now) possible to run SQL directly in a CL program without using QM Query, RUNSQLSTM or QShell.
Here is an article that discusses the RUNSQL statement in CL programs...
http://www.mcpressonline.com/cl/the-cl-corner-introducing-the-new-run-sql-command.html
The article contains information on what OS levels are supported as well as clear examples of several ways to use the RUNSQL statement.
This will work in two steps:
RUNSQL SQL('CREATE TABLE QTEMP/REPORT AS (SELECT +
EXTRACT_DATE , SYSTEM, ODLBNM, SUM( +
OBJSIZE_MB ) AS LIB_SIZE FROM +
ZSYSCOM/DISKRPTHST WHERE ODLBNM LIKE +
''SIS%'' GROUP BY EXTRACT_DATE, SYSTEM, +
ODLBNM ORDER BY LIB_SIZE DESC) WITH +
DATA') COMMIT(*NONE) DATFMT(*USA) DATSEP(/)
RUNQRY QRYFILE((QTEMP/REPORT)) OUTTYPE(*PRINTER) +
OUTFORM(*DETAIL) PRTDFN(*NO) PRTDEV(*PRINT)
The first step creates a temporary table result in qtemp and the second step/line runs an adhoc query over just the temporary table to a spool file.
Thanks,
Michael Frilot
There is of course a totally different solution: You could write and compile a program containing the statement. It requires some longer reading into, especially if you are new to the platform, but it should give you most flexibility over what you do with results. You can use SQL in C, C++, RPG, RPG/LE, REXX, PL (of which I don't know, what it is) and COBOL. Doing that, you can react in any processable way on results from one query and start/create other queries based on what you get.
Although some oldfashioned RPG-programmers try everything to deny SQL in RPG exists, it is possible today for many cases, to write RPG-programs with SQL only and no direct file access (without F-Specs, for those who know RPG).
If your solution works for you, perfect. If you need to do something else, try a look into this pdf: http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/rzajp/rzajp.pdf
The integration into RPG is not too bad. It works with the normal program flow. Would look something like this (in free form):
/free
// init search values:
searchval = 'Someguy';
// so the sql query:
exec sql
SELECT colum1, colum2
INTO :var1, :var2
FROM somelib/somefile
WHERE keycol=:searchval;
// now do something with the values:
some_proc(var1);
/end-free
In this, var1, var2, and searchval are ordinary RPG-variables. No quoting needed. Works also with datastructures (externally defined e.g., the record format of the file itself fits well). You can work with cursors and loops, too, of course. I feel that RPG-programs tend to be easier to read with this.