From: Dave Hughes on
Ian Boyd wrote:

> > Ian, what tool are you using. This works for me using CLP
> > Please clarify your environment.
>
> i've tried a couple:
>
> - Microsoft ADO using the IBM DB2 driver for ODBC

This is usually the best option I've found -- the DB2 ODBC driver is
very feature-complete (not surprising given that the DB2 CLI basically
*is* ODBC)

> - Microsoft ADO using the IBM DB2 OLEDB Provider

Generally, I'd avoid this one. For some reason, the DB2 OLEDB provider
lacks some things. For example, I've found in the past that the
meta-data retrieval calls don't work with the native DB2 OLEDB
provider, while they will if you use the DB2 ODBC driver via the MS
OLEDB ODBC provider. Mind you, that was a while ago -- might be fixed
in more recent versions.

> - 3rd party program called "WinSQL" which connects through an ODBC
> DSN (with it's built-in statement delimiter changed to =)
>
> - IBM Command Editor (db2ce.bat) with it's "Statement termination
> character" changed to =

Hmmm, using = as a statement terminator is probably a bad idea (given
the ambiguity). I'd recommend @ (which seems to be an accepted
standard) or ! as I don't think either appear anywhere in the DB2
grammar (well, that's not strictly true for ! but it's only used for
some backward compatibility operators if I recall correctly).

> i'll show you the detailed results from IBM Command Editor, as it
> returms more error information than the simple exception thrown by
> ADO from the ODBC for OLEDB providers.
>
> <quote>
> ------------------------------ Commands Entered
> ------------------------------ INSERT INTO Daily_Logs (
> Daily_Log_Number, Created_By_User_ID, Property_ID, Shift_ID,
> Bay_Number, Supervisor_User_ID, Location_ID, Occurrence_ID,
> Checklist_ID, Daily_Log_Type_ID, Daily_Log_SubType_ID,
> Start_Date, End_Date, Description)
> VALUES (
> 'DL-20060307-3', --DailyLogNumber
> 0, --CreatedByUserID
> 1, --PropertyID
> 1, --ShiftID
> 'A74', --BayNumber
> 1, --SupervisorUserID
> 2, --LocationID
> CAST(NULL AS bigint), --Occurrence_ID (must manually cast nulls)
> CAST(NULL AS bigint), --ChecklistID (must manually cast nulls)
> 2, --DailyLogTypeID
> 5, --DailyLogSubTypeID
> '2006-03-01 11:11:07.11111', --StartDate
> '2006-03-01 11:21:18.22222', --EndDate
> CAST(NULL AS varchar(1)) --Description (must manually cast nulls)
> );=

Hmmm ... you shouldn't need those CASTs around the NULLs, not in an
INSERT statement anyway. Let me just try it:

db2 => CREATE TABLE TEST (
db2 (cont.) => A INTEGER DEFAULT NULL,
db2 (cont.) => B BIGINT DEFAULT NULL,
db2 (cont.) => C VARCHAR(1) DEFAULT NULL
db2 (cont.) => );
DB20000I The SQL command completed successfully.

db2 => INSERT INTO TEST (A, B, C) VALUES
db2 (cont.) => (1, 2, NULL),
db2 (cont.) => (2, NULL, 'A'),
db2 (cont.) => (NULL, NULL, NULL);
DB20000I The SQL command completed successfully.

db2 => SELECT * FROM TEST;

A B C
----------- -------------------- -
1 2 -
2 - A
- - -

3 record(s) selected.


Yup, works for me without CASTs. That's because the data type can be
inferred from the type of the target column in this case. That said,
DB2 does require a CAST around NULLs in certain places. For example,
consider a SELECT:

db2 => SELECT NULL, B, C FROM TEST;
SQL0206N "NULL" is not valid in the context where it is used.
SQLSTATE=42703

db2 => SELECT CAST(NULL AS INTEGER), B, C FROM TEST;

1 B C
----------- -------------------- -
- 2 -
- - A
- - -

3 record(s) selected.


In this case it's because a NULL on its own has no datatype, and each
column in a query result *must* have a datatype. Ergo, the NULL must be
cast to some datatype in this particular case.

Incidentally, this often causes confusion with the set operators
(UNION, INTERSECT and EXCEPT). For example (again using the TEST table
from above):

db2 => SELECT A, B, C FROM TEST
db2 (cont.) => UNION
db2 (cont.) => SELECT NULL, B, C FROM TEST;
SQL0206N "NULL" is not valid in the context where it is used.
SQLSTATE=42703

db2 => SELECT A, B, C FROM TEST
db2 (cont.) => UNION
db2 (cont.) => SELECT CAST(NULL AS INTEGER), B, C FROM TEST;

1 B C
----------- -------------------- -
2 - A
- - A
1 2 -
- 2 -
- - -

5 record(s) selected.


One could argue that, in this case DB2 ought to be able to figure out
that the NULL in the query on the right-hand side of the UNION should
be implicitly cast to an INTEGER as that is the datatype of the first
column in the query on the left-hand side of the UNION.

However (I suspect) the order of execution doesn't allow for this. In
other words, DB2 first attempts to evaluate the left-hand and
right-hand queries, then attempts to evaluate the UNION operation.
Because the right-hand query can't be evaluated, the statement fails
(before ever getting to the UNION). Think about it like a mathematical
evaluation, and it makes sense:

(expression1) + (expression2)

Despite the + being infix here (like the UNION operator in the queries
above), expression1 and expression2 must obviously be evaluated first
before the addition can be evaluated.


[snip]
> > PS: I find this thread quite interesting actually.
> In a morbid train-wreck sorta way?
>
> i'm approaching DB2 from a very high-level (and overview if you
> will). It's not like i don't understand relational databases. i think
> i am very used to SQL Server, where it is very powerful and yet very
> friendly. If you accept that most enterprise class RDBMS are of a
> similar feature set, the different between is semantics, and tools,
> and language.
>
> i'm walking a fine line here. There are things in DB2 that make no
> sense. They are, quite plainly, non-sensical. i try to explain what i
> think the vision and philosophy that DB2 has for doing things - as
> though there was an all-encompassing grand vision for everything. But
> things are not that way. Due to historical design decisions,
> backwards compatiblity, forward compatiblity, standards
> compatability, etc things can make little sense to an outside
> observer. Which is fine, as long as i can quickly find the list of
> all these different design paradigms. But many zealots will take my
> confusion and frustration of the scattered design as an insult, and
> thats a tough needle to thread, especially in a DB2 newsgroup - where
> i am stating up front i come from Microsoft SQL Server, and a lot of
> people in here have used the word "Micro$oft".

Hmm, I'd say there's very little in DB2 that's non-sensical, and
generally I do find there is a philosophy behind DB2's way of doing
things. But as I mentioned in another post, I'm beginning to understand
just how alien it must seem when "switching philosophies" so to speak.

The VALUES expression, to me, is a good example of "DB2's philosophy".
A number of other databases use

SELECT <value>, <value>, ...

as a way of generating a row on an adhoc basis. However, it's unclear
with this syntax how one could generate an adhoc *table*. As someone
else mentioned, in SQL "everything is a table" (a single row is just a
special case of a table, and a single value is another such special
case). Extending this syntax to generate multiple rows like so:

SELECT (<value>, <value>, ...), (<value>, <value>, ...)

*is* non-sensical as one cannot specify multiple rows in the first part
of a SELECT expression against a table. Therefore using SELECT in this
fashion violates the principal that "everything is a table". Hence, DB2
uses the VALUES expression

VALUES (<value>, <value>, ...), (<value>, <value>, ...)

to generate an adhoc table. This, in turn, fits in neatly with the
INSERT statement as now the general syntax for INSERT can be:

INSERT INTO <table> (<column>, <column>, ...) <data>

Where <data> is some expression that returns a table such as a SELECT
expression, or a VALUES expression. Therefore, one can insert multiple
rows into a table with:

INSERT INTO mytable (cola, colb, colc)
VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9);

or

INSERT INTO mytable (cola, colb, colc)
SELECT cola, colb, colc FROM myothertable

This is also why I frown upon the syntax MySQL uses for INSERT:

INSERT INTO mytable SET cola=vala, colb=valb, ...

(although admittedly MySQL can also use the standard VALUES syntax). I
suspect they introduced this other syntax to make INSERT look more like
UPDATE but it doesn't "fit" when you start thinking about "everything
is a table".

Speaking of UPDATE, the UPDATE statement has never really "fit" the
"everything is a table" philosophy particularly well. It seems like the
new MERGE statement (introduced in either SQL-99 or SQL-2003, I forget
which) is an attempt to address this.

But enough philosophical ramblings... Suffice it to say that there does
appear (to a long-time user) to be a "grand design" to the way DB2's
SQL grammar is structured.

> Also, when dealing with, and writing many user interfaces, i have
> become picky about programs or systems that cannot do what a user
> expects. So some of IBM's graphical tools, and SQL language itself,
> can leave much to be desired from a usability point of view.

I suspect you'll be preaching to the choir with regard to the graphical
tools. I can't remember a single occassion of someone *praising* the
graphical tools! No design philosophy here, or at least none I've ever
figured out.

Personally, I stick with the command line (combined with a decent shell
like bash under Linux it's very powerful, though I'll admit that's
little comfort to anyone not wishing to use a command line for whatever
reason).

> i'm walking a fine line here: of trying to extract information from
> the people in the know, without touching a nerve.

You're doing a good job so far I'd say.

--

From: Dave Hughes on
Serge Rielau wrote:

> Dave Hughes wrote:
> > In this case, unfortunately, the only solution is to chop out the
> > comments altogether (shame DB2 doesn't support C-style /*..*/
> > comments in which line break chopping doesn't result in ambiguity).
> db2 => select /* hello */ 1 from sysibm.sysdummy1;
>
> 1
> -----------
> 1
>
> 1 record(s) selected.
>
> DB2 V8.2.2 (FP9)
>
> Since Ian has all those drivers maybe he can try it.
>
> Cheers
> Serge

db2 => select /* hello */ 1 from sysibm.sysdummy1;
SQL0104N An unexpected token "select /* hello */ 1" was found
following
"BEGIN-OF-STATEMENT". Expected tokens may include: "<space>".
SQLSTATE=42601

$ db2level
DB21085I Instance "db2inst1" uses "32" bits and DB2 code release
"SQL08020"
with level identifier "03010106".
Informational tokens are "DB2 v8.1.0.64", "s040812", "MI00086", and
FixPak "7".
Product is installed at "/opt/IBM/db2/V8.1".

Hmmm, time to upgrade the fixpak I guess! (I don't usually bother with
every fixpak on this box as it's just a test box not accessible outside
the local LAN, so security's not a big concern).


Cheers,

Dave.

--

From: Mark A on
"Dave Hughes" <dave(a)waveform.plus.com> wrote in message
news:440f7a23$0$70294$ed2619ec(a)ptn-nntp-reader03.plus.net...
> Hmmm, time to upgrade the fixpak I guess! (I don't usually bother with
> every fixpak on this box as it's just a test box not accessible outside
> the local LAN, so security's not a big concern).
>
>
> Cheers,
>
> Dave.
>

Aside from security fixes, there have been about 1500 other APAR's fixed
since then (assuming that you install FP11).


From: Gert van der Kooij on
In article <dunkro0q4f(a)enews3.newsguy.com>, Ian Boyd (ian.msnews010
@avatopia.com) says...
> The progress so far. Note, this is mainly for me, and my coworkers who want
> help understanding the limitations of DB2. This post will be google
> archived, and available as a future reference.
>
> DO NOT RESPOND

Sorry, I don't agree. I do respond because it contains errors.
>
>
> 7. Every DB2-SQL Statement must end with a semi-colon (;)
>
> 8. You cannot give DB2 some arbitrary SQL to run.

This isn't right, it depends. If you put multiple commands in one
file you need to seperate them.

If you put the following commands in one file you can run them
without a semi-colon _as_long_as_you_put_one_statement_on_one_line.
The end-of-line is the default statement delimiter.

empl_test.sql contains:

connect to sample
select * from employee
insert into employee (<column names>) values (< values>)
connect reset

run it from the Command Window with:
db2 -f empl_test.sql


If you want to a statement to span multiple lines you need to
seperate them by a command delimiter. The default delimiter is the
semi-colon.

connect to sample;
select *
from employee
where EMPNO > 10;
connect reset;

use the '-t' option to run it from the Command Window with:
db2 -tf empl_test.sql


If you want to create a trigger or procedure you need to seperate the
statements within them with a semi-colon. Because of that the 'create
function' and 'create trigger' statements needs to be seperated by
another delimiter.

To create your trigger using an input file you can do the following:

trg_define.sql contains:

connect to <yourdb> @

CREATE TRIGGER SUPERDUDE.LI_DAILYLOGS
AFTER INSERT
ON SUPERDUDE.DAILY_LOGS
REFERENCING NEW_TABLE AS INSERTED
FOR EACH STATEMENT
BEGIN ATOMIC
-- Load the saved UserID
DECLARE SavedUserID INTEGER;

SET SavedUserID = (SELECT User_ID
FROM Connection_Users
WHERE Application_ID = Application_ID());

INSERT INTO Audit_Log(
RowID,
ChangeType,
UserID,
TableName,
FieldName,
Username,
Hostname,
Appname,
TagID,
Tag,
OldValue,
NewValue)
SELECT
i.Daily_Log_ID,
'INSERTED',
SavedUserID,
'Daily_Logs',
'',
SESSION_USER,
CURRENT CLIENT_WRKSTNNAME,
CURRENT CLIENT_APPLNAME,
i.Daily_Log_ID,
i.Daily_Log_Number,
CAST(NULL AS varchar(1)),
CAST(NULL AS varchar(1))
FROM Inserted i;
END@

connect reset@

and run it from the command window with the following command
db2 -t@ -f trg_define.sql


The example provided by you contains an error, it's missing the
finishing ')' in the CREATE TABLE statement. The statements below can
be run at once without a problem.

CREATE TABLE Users (
UserID int,
Username varchar(50));
INSERT INTO Users (UserID, Username) VALUES (1, 'Ian');
INSERT INTO Users (UserID, Username) VALUES (2, 'Brian');
INSERT INTO Users (UserID, Username) VALUES (3, 'Knut');
INSERT INTO Users (UserID, Username) VALUES (4, 'Serge');
SELECT * FROM Users
WHERE Username = 'Knut';
DROP TABLE Users;

If you put them in a file multiple_statements.sql it can be run at
once with the command:

db2 -tf multiple_statements.sql


Hope this helps.

Regards, Gert
From: Brian Tkatch on
>was referring to (an older version of) the SQL Reference for DB2 on zOS ("Mainframe").

Version 8 for LUW.

Or at least that's what they have on the corparate intranet.

B.

First  |  Prev  |  Next  |  Last
Pages: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
Prev: SQL0901N Error.
Next: Convert DECIMAL to DATE