I am attempting to tune our oracle database that has been running a little slowly lately.
I have generated a SQL trace file, and can run the basic TKPROF from the command prompt, and generate the appropriate output file.
tkprof.exe source.trc output.txt
I would very much like to see the execution plan as well since there are a good number of indexes that should be used with this database. To do this, I am trying to run this:
tkprof.exe source.trc output.txt EXPLAIN=mbw/password
The problem is, the username which every application uses to connect with is lowercase (mbw for this example, and I have to leave it this way). So whenever I wish to look at data, I have to put quotes around the user like this:
SELECT * FROM "mbw".TABLE1
Unfortunately, I can never seem to get TKPROF to connect as "mbw"/password, it is always as mbw/password, which will never work. (I can see what TKPROF is attempting to connect with in the output.txt file)
I have tried a bunch of permutations on the command line, and just can't seem to make it happen. I've tried things like:
... EXPLAIN="mbw"/password
... EXPLAIN=""mbw""/password
... EXPLAIN="""mbw"""/password
... EXPLAIN=^"mbw^"/password
Does anyone have any ideas on how to properly structure the TKPROF command so I can connect as a user with lowercase letters?
I fully apologize for my lack of good oracle and sql skills, I have been rather unexpectedly thrown into this particular job and am trying to learn as fast as I can.
Related
I am currently taking CS50, an online introductory course in coding by Harvard. We have just covered SQL and I am trying to attempt the question "Movies" in the problem set now, a description of which can be found here: https://cs50.harvard.edu/x/2020/psets/7/movies/
However, I am not sure how to do this correctly.
For example, for 1.sql, my code is as follows:
SELECT title FROM movies WHERE year = 2008;
I literally wrote only that one line and nothing more in the file "1.sql".
But when I run
$ cat 1.sql | sqlite3 movies.db
in my terminal, nothing happens?
Is this how I am supposed to write code for SQL? Or am I missing some stuff that I should be including (e.g. as headers or what) above my query?
To be clear, I believe I know how to write a query itself but I do not know the "protocol" to write it, if I may. I mean, for example, I am positively sure that "SELECT title FROM movies WHERE year = 2008;" fulfils the question's first requirement.
Some enlightenment would be appreciated!
EDIT 1
Okay first I must apologise to everyone who so very kindly took the time to comment on my post. For some very odd reason, my query did not return any results the first time I ran it. However, when I tried it again, it worked perfectly! Not sure what went wrong honestly, but all is well now! So sorry for wasting everyone's time ):
EDIT 2
Okay I also figured out that the reason why I could not execute my query is that I was in "sqlite3" in my terminal. I was supposed to run the command to execute my query in the main terminal i.e. not when it says "sqlite3". Stupid. I know.
Option 1) you can run "$ cat 1.sql | sqlite3 movies.db" in your normal terminal (not in the sqlite3 mode)
Option 2) you can open sql environment by typing "sqlite3 movies.db" (it will open movies.db if it exists, or create a temporary one if it doesn't exist). Then you can type ".read 1.sql" after the "sqlite>"
Open Browser and test it as mention on your course site
Usage
To test your queries on CS50 IDE, you can query the database by running
$ cat filename.sql | sqlite3 movies.db
where filename.sql is the file containing your SQL query.
Or you can paste them into DB Browser for SQLite’s Execute SQL tab and click ▶.
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.
I've a Postgresql database on my server and I would like to use it for a simple web-app on localhost. I've set the Database to allow my connections ecc.. In fact, my web-app can connect to the DB... But all the queries give no result in local. (That's funny because all the queries work great on the server.
Can you help me?
The first thing to do is this:
Login via psql, and run the following query (note the terminating semicolon):
SELECT version();
If that works, check to make sure you are terminating the queries with semicolons.
If that doesn't work, please copy/paste the complete output of psql (including prompts and greetings) here.
As a note, the psql prompt is very informative. The most important character for this purpose is the second from the right. That starts out as =, but changes to - if it is a continuation of a new line, ' if there is an unterminated single quote, " if there is an unterminated double quote, etc.
Question
Hi,
I'm trying to determine if I can query Intersystems Caché to obtain database properties and license properties. For the database, I'm mostly interested in properties like the current size, maximum size, block size, and the directory associated with the database. For the licenses, I'm total authorized, current available, minimum available, current active users, and maximum active users.
Background
I know that details about the database and licenses are available using the System Management Portal, but I'm trying to automate some actions that depend on these details.
I know that the %FREECNT utility is available to display space statistics for the database, but the only way I'll be able to use this utility to obtain the info I need is to write a script using AWK or SED (the system is on a Unix server) and I'd like to avoid that since I'm not as well-versed in Unix scripting as I'd like to be.
I know the ^DATABASE routine and the $SYSTEM.License.ShowCounts() function are available, but I will have to use AWK and SED for these too to eliminate the text returned that I don't need. In all cases, straight SQL will return a set of data that I can iterate over that will eliminate the extraneous text that's included by the routines/functions.
Additional Info
I've written queries similar to the one below and I'm hoping there are equivalent tables for database and license that will allow me the same access:
Select * From %SYS.ProcessQuery Where Namespace = 'HL7'
I don't have access to Caché Studio, so I'm forced to use the command line on the server. I know I can use the SQL.Shell to enter SQL statements and, from the documentation, it looks like I can create routines from the command line, but I haven't found any documentation that will allow me to enter multiline statements for routines from the command line. If that's not possible, then I probably can't use routines in my solution.
Thanks for the help.
In your Caché routine, you can use Query Summary for get some license information, or other queries in class %SYSTEM.License
For Databases you can use queries from SYS.Database from %SYS namespace
I was able to get something close.
From the command line, I entered the following:
%SYS>SET rs = ##Class(%Library.ResultSet).%New()
%SYS>SET rs.ClassName = "SYS.Database"
%SYS>SET rs.QueryName = "FreeSpace"
%SYS>SET sc = rs.Prepare(rs.QueryName)
%SYS>SET sc = rs.Execute($LISTBUILD("/my/database/directory"), 0)
%SYS>WHILE rs.Next(){WRITE rs.Data("DatabaseName")," "_rs.Data("Size")," "_rs.Data("MaxSize"),!}
It's not quite as clean as I would have hoped because I have to write the entire loop on a single line, but that's better than nothing. At least the statement wraps across lines.
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.