我有一个 C# 应用程序,需要验证 DB2 数据库(V7R3)的凭据。
我们过去的做法是将凭据附加到连接字符串并实际尝试连接到数据库,看看连接是成功还是失败。
但是有没有更好的方法来做到这一点,比如用于测试凭证的 API 之类的?
我有一个 C# 应用程序,需要验证 DB2 数据库(V7R3)的凭据。
我们过去的做法是将凭据附加到连接字符串并实际尝试连接到数据库,看看连接是成功还是失败。
但是有没有更好的方法来做到这一点,比如用于测试凭证的 API 之类的?
我正在尝试将生成的列添加到 IBM DB2 V7R3 中的表中:
ALTER TABLE MYLIB.MYTABLE
ADD COLUMN NEW_COL VARCHAR(255) GENERATED ALWAYS AS (
COALESCE(
CASE
WHEN ENV = 'A' THEN (SELECT GUIDE_URL FROM MYLIBA.PROGRAM WHERE CODE = PGM)
WHEN ENV = 'B' THEN (SELECT GUIDE_URL FROM MYLIBB.PROGRAM WHERE CODE = PGM)
ELSE (SELECT GUIDE_URL FROM MYLIBC.PROGRAM WHERE CODE = PGM)
END
, URL
)
)
但它给出了以下错误:
SQL 状态:42601 供应商代码:-199 消息:[SQL0199] 不需要关键字 WHEN。有效令牌: . ACCTNG 用户 ID 应用程序名称 程序 WRKSTNNAME。原因 。。。。。:此处不需要关键字 WHEN。在关键字 WHEN 处检测到语法错误。有效令牌的部分列表是 。ACCTNG 用户 ID 应用程序名称 程序 WRKSTNNAME。此列表假定语句在意外关键字之前都是正确的。该错误可能出现在语句的前面,但到目前为止该语句的语法似乎是有效的。恢复 。。。:检查指定关键字区域的SQL语句。冒号或 SQL 分隔符可能会丢失。SQL 要求保留字在用作名称时进行分隔。更正 SQL 语句并再次尝试请求。
难道我做错了什么?或者在 7.3 中创建这样的生成列是不可能的吗?升级到 7.5 有帮助吗?我试图找到有关可以在哪些版本中生成哪些生成的列的详细信息,但在文档中找不到任何内容。
尝试计算 FIFO 报告的值。有没有一种方法使用 SQL 对数据进行分组,以便将特定值的总和与每个组的不同值进行比较,包括在必要时仅取行的一部分?
请求:对于每个商品编号,按日期对已购买商品进行降序排序,并获取最大金额,使数量总和 = 该商品编号的已售出金额,如有必要,仅取最后一行的一部分获得匹配的数量。然后输出未售出剩余库存的结果,其中包含 ItemNumber、NumShipments 和 CostSum(CostPer 与 Quantity 的乘积之和)。
例如,考虑以下架构:
CREATE TABLE MYLIB.TOTAL_ITEM_SOLD (ITEM_NUMBER VARCHAR(15) NOT NULL NOT HIDDEN , QUANTITY_SOLD DECIMAL(5, 2) NOT HIDDEN , PRIMARY KEY (ITEM_NUMBER) ) NOT VOLATILE UNIT ANY KEEP IN MEMORY NO ;
CREATE TABLE MYLIB.ITEM_PURCHASE (ITEM_NUMBER VARCHAR(15) NOT NULL NOT HIDDEN , DATE_ORDERED TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP NOT NULL NOT HIDDEN , QUANTITY DECIMAL(4, 2) NOT NULL NOT HIDDEN , COST_PER DECIMAL(10, 2) NOT NULL NOT HIDDEN , PRIMARY KEY (DATE_ORDERED, ITEM_NUMBER) ) NOT VOLATILE UNIT ANY KEEP IN MEMORY NO ;
INSERT INTO MYLIB.TOTAL_ITEM_SOLD (ITEM_NUMBER, QUANTITY_SOLD) VALUES ('APPLE', 5);
INSERT INTO MYLIB.ITEM_PURCHASE (ITEM_NUMBER, QUANTITY, COST_PER) VALUES ('APPLE', 2, 1.23);
INSERT INTO MYLIB.ITEM_PURCHASE (ITEM_NUMBER, QUANTITY, COST_PER) VALUES ('APPLE', 4, 2.34);
INSERT INTO MYLIB.ITEM_PURCHASE (ITEM_NUMBER, QUANTITY, COST_PER) VALUES ('APPLE', 2, 5.55);
预期结果:
{ITEM_NUMBER: "APPLE", QTY_REMAINING: 3, COST_SUM: 13.44}
因为 5.55+5.55+2.34 = 13.44。
有没有一种方法使用 SQL 对数据进行分组,以便将特定值的总和与每个组的不同值进行比较?
例如,考虑以下架构:
Table: ITEM
Columns:
ITEM_NUMBER (VARCHAR(15))
QUANTITY_ON_HAND (DECIMAL(5,2))
Primary Key: ITEM_NUMBER
Table: ORDER_ITEM_REQUIREMENTS
Columns:
ITEM_NUMBER (VARCHAR(15), Foreign Key to ITEM)
DATE_ORDERED (TIMESTAMP)
QUANTITY (DECIMAL(4,2))
COST_PER (DECIMAL(10,2))
Primary Key: ITEM_NUMBER+DATE
请求:对于每个项目编号,按日期升序排列订单项目要求,并获取最大数量,使数量总和 <= 该项目编号的现有数量(如果总和为 1,则获取所有订单项目要求)小于现有数量)。然后输出包含 ItemNumber、NumShipments、QtySum 和 CostSum(CostPer 与 Quantity 的乘积之和)的结果。
如果重要的话,我们正在使用 IBM DB2 Version 7 Revision 3。
例如,给定以下数据:
{ITEM_NUMBER: "APPLE", QUANTITY_ON_HAND: 5}
{ITEM_NUMBER: "APPLE", DATE_ORDERED: Jan 1, 12:01, QUANTITY: 2, COST_PER: 1.23}
{ITEM_NUMBER: "APPLE", DATE_ORDERED: Jan 1, 12:02, QUANTITY: 2, COST_PER: 2.34}
{ITEM_NUMBER: "APPLE", DATE_ORDERED: Jan 2, 12:03, QUANTITY: 2, COST_PER: 5.55}
或者用 SQL 来说:
CREATE TABLE MYLIB.ITEM (ITEM_NUMBER VARCHAR(15) NOT NULL NOT HIDDEN , QUANTITY_ON_HAND DECIMAL(5, 2) NOT HIDDEN , PRIMARY KEY (ITEM_NUMBER) ) NOT VOLATILE UNIT ANY KEEP IN MEMORY NO ;
CREATE TABLE MYLIB.ORDER_ITEM_REQUIREMENTS (ITEM_NUMBER VARCHAR(15) NOT NULL NOT HIDDEN , DATE_ORDERED TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP NOT NULL NOT HIDDEN , QUANTITY DECIMAL(4, 2) NOT NULL NOT HIDDEN , COST_PER DECIMAL(10, 2) NOT NULL NOT HIDDEN , PRIMARY KEY (DATE_ORDERED, ITEM_NUMBER) , FOREIGN KEY (ITEM_NUMBER) REFERENCES MYLIB.ITEM (ITEM_NUMBER) ON DELETE NO ACTION ON UPDATE NO ACTION ) NOT VOLATILE UNIT ANY KEEP IN MEMORY NO ;
INSERT INTO MYLIB.ITEM (ITEM_NUMBER, QUANTITY_ON_HAND) VALUES ('APPLE', 5);
INSERT INTO MYLIB.ORDER_ITEM_REQUIREMENTS (ITEM_NUMBER, QUANTITY, COST_PER) VALUES ('APPLE', 2, 1.23);
INSERT INTO MYLIB.ORDER_ITEM_REQUIREMENTS (ITEM_NUMBER, QUANTITY, COST_PER) VALUES ('APPLE', 2, 2.34);
INSERT INTO MYLIB.ORDER_ITEM_REQUIREMENTS (ITEM_NUMBER, QUANTITY, COST_PER) VALUES ('APPLE', 2, 5.55);
我想要以下结果:
{ITEM_NUMBER: "APPLE", NUM_SHIPMENTS: 2, QTY_SUM: 4, COST_SUM: 7.14}
我们无法删除别名。所以,我通过运行找到了一个别名:
SELECT
TABLE_NAME
FROM
QSYS2.SYSTABLES
WHERE
BASE_TABLE_NAME IN ('OE0711P','OE0712P')
AND TABLE_TYPE = 'A'
AND SYSTEM_TABLE_SCHEMA = 'AMPLIBX';
并选择了第一个,即OE0712PD506202270
.
所以我尝试运行DROP ALIAS AMPLIBX.OE0712PD506202270;
并出现以下错误:
SQL 状态:42704
供应商代码:-204
消息:[SQL0204] AMPLIBX 类型 *FILE 中的 OE07100001 未找到。原因 。. . . . : AMPLIBX 类型 *FILE 中的 OE07100001 未找到。如果成员名称是*ALL,则该表未分区。如果这是一个 ALTER TABLE 语句并且类型是 *N,则未找到约束或分区。如果这不是 ALTER TABLE 语句且类型为 *N,则未找到函数、过程、触发器或序列对象。如果未找到函数,则 OE07100001 是包含该函数的服务程序。除非外部名称和用法名称完全匹配,否则不会找到该函数。检查作业日志中是否有一条消息提供了有关正在搜索哪个函数名称以及不匹配的名称的更多详细信息。恢复 。. . : 更改名称并重试请求。如果对象是节点组,确保在您的系统上安装了 DB2 Multisystem 产品并使用 CRTNODGRP CL 命令创建节点组。如果未找到外部函数,请确保 CREATE FUNCTION 语句中 EXTERNAL NAME 的大小写与服务程序导出的名称的大小写完全匹配。
工作日志只说:
AMPLIBX 类型 *FILE 中的 OE07100001 未找到。
……可是怎么会找不到呢?我真的只是在元数据中找到它。
另请注意:尝试通过 IBM i Access Client Solutions 应用程序删除时也会出现奇怪的行为。
难道我做错了什么?我怎样才能删除这些别名?
当我尝试运行如下查询时:
MERGE INTO
MYTABLE_A
AS MERGE_TARGET
USING
(
SELECT
MYTABLE_A.A, MYTABLE_B.B, MYTABLE_A.C, MYTABLE_D, MYTABLE_E
FROM
MYTABLE_A
INNER JOIN MYTABLE_B
ON MYTABLE_B.A = MYTABLE_A.A
WHERE
MYTABLE_A.LOGIC = 1
AND MYTABLE_B.LOGIC = 2
) AS MERGE_USING
ON MERGE_USING.C = MERGE_TARGET.C
AND MERGE_TARGET.OTHERLOGIC = 1
AND MERGE_TARGET.A IN (
SELECT
MYTABLE_A.A
FROM
MYTABLE_A
INNER JOIN MYTABLE_B
ON MYTABLE_B.A = MYTABLE_A.A
WHERE
MERGE_USING.B = MYTABLE_B.B
)
WHEN MATCHED THEN UPDATE SET
MERGE_TARGET.D = MERGE_USING.D,
MERGE_TARGET.E = MERGE_USING.E
它给了我这个错误:
消息:[SQL0115] 比较运算符 IN 无效。原因 。. . . . : 除了等于和不等于之外的简单比较运算符不能与项目列表一起使用。ANY、ALL 和 SOME 比较运算符后面必须跟一个全查询,而不是表达式或项目列表。不能在 JOIN 条件或 CASE 表达式中指定子查询。恢复 。. . :更改比较或操作数。再次尝试请求。
DB2 版本:V7R1
我有一张桌子,上面有以下内容:
Columns:
---
URL [nullable, e.g. "https://dba.stackexchange.com/"]
APPFK [nullable, e.g. 654654]
LINKTYPE ["Page", "Link", or "App"]
Check Constraints:
---
(URL IS NULL AND LINKTYPE <> "Link") OR (URL IS NOT NULL AND LINKTYPE = "Link")
(APPFK IS NULL AND LINKTYPE <> "App") OR (APPFK IS NOT NULL AND LINKTYPE = "App")
由于可以根据 URL 和 APPFK 的可空性计算 LinkType,我认为这是计算/生成/虚拟列的绝佳机会。
所以,我试图运行:
alter table MYLIB.MYTABLE
add column testcol VARCHAR(4) generated always as
(
CASE
WHEN URL IS NOT NULL THEN 'LINK'
WHEN APPFK IS NOT NULL THEN 'APP'
ELSE 'PAGE'
END
)
Annnd DB2 向我吐口水:
SQL 状态:42601 供应商代码:-104 消息:[SQL0104] 令牌(无效。有效令牌:IDENTITY。原因......:在令牌(。令牌(不是有效令牌。A有效标记的部分列表是 IDENTITY。此列表假定该语句在该标记之前是正确的。错误可能在该语句的早期,但该语句的语法在此之前似乎是有效的。恢复...:执行以下一项或多项操作并再次尝试请求: -- 验证令牌区域中的 SQL 语句 (。更正语句。错误可能是缺少逗号或引号,也可能是拼写错误的单词,或者它可能与子句的顺序有关。- 如果错误标记是 ,请更正 SQL 语句,因为它没有以有效的子句结尾。
我尝试运行此 DB2 文档中的第一个示例,但它给了我同样的错误。
怎么了,这里?难道我做错了什么?文档有错吗?仅仅是因为我们的 DB2 已经过时(我们运行的是版本 7,修订版 1),如果是,是否有解决方法?
所以,我有一个查询来列出我们的 RPG 程序:
SELECT OBJNAME
FROM
(SELECT OBJNAME AS SCHEMA FROM TABLE (QSYS2.OBJECT_STATISTICS('*ALLSIMPLE', 'LIB')) S) AS SCHEMAS
,LATERAL (SELECT * FROM TABLE(QSYS2.OBJECT_STATISTICS(SCHEMAS.SCHEMA, 'PGM')) X) AS PROGRAMS
LEFT JOIN QSYS2.PROCEDURES
ON QSYS2.PROCEDURES.PROCNAME = PROGRAMS.OBJNAME
AND QSYS2.PROCEDURES.PROCSCHEMA = PROGRAMS.OBJLONGSCHEMA
WHERE
PROCNAME IS NULL
AND SCHEMAS.SCHEMA = 'MYLIB'
;
现在,给定一个 RPG 程序的名称,有什么方法可以通过 SQL 获取它的内容吗?
(或者,失败的 SQL,从 C# 应用程序中获取内容的其他方式?)
我正在尝试运行这个:
ALTER TABLE AMMLIBT.SAGRPPF ADD UNIQUE (ID) ADD CHECK ( IS_BUDGETABLE IN ( 0 , 1 )) ;
这给了我这个:
SQL 状态:55019
供应商代码:-7008
消息:[SQL7008] AMMLIBT 中的 SAGRPPF 对操作无效。原因 。. . . . :原因码是10。原因码是:
[...]
10 -- 正在向无效类型的表添加约束或触发器,或已达到最大触发器数,或分布式表的所有节点不在同一发布级别。
[...]
恢复 。. . :根据原因码执行以下操作之一:
[...] 10 -- 指定对约束或触发器有效的表。
[...]
...而且我不知道为什么而且似乎无法在网上找到任何解释这一点的东西。
该表已记录,我已删除所有家属。
我在 IBM DB2 V7R1
我该如何解决?
所以我们目前有以下内容:
MYTABLE
COLUMN: ID (INTEGER Primary key, auto-incrementer)
COLUMN: START (DATE)
COLUMN: COMPANYID (INTEGER, Foreign key to COMPANY)
COLUMN: DELETED (INTEGER)
CHECK: DELETED = 0 OR DELETED = 1
现在,要求允许无限删除记录,但每个日期+公司只允许一条未删除记录。
我建议将架构更改为:
MYTABLE
COLUMN: ID (INTEGER Primary key, auto-incrementer)
COLUMN: START (DATE)
COLUMN: COMPANYID (INTEGER, Foreign key to COMPANY)
COLUMN: ACTIVE (Nullable INTEGER)
CHECK: ACTIVE = 1 OR ACTIVE IS NULL
UNIQUE: START, COMPANYID, ACTIVE
虽然我的同事认为这“太过分了”,但我们应该只依赖应用程序中的唯一性检查。
这里有普遍接受的最佳实践吗?
假设我有一个在 MYLIB 中创建 50 个表的 C# 脚本。
目前,在运行脚本后,我必须进入 System i Navigator 并手动将 MYLIB/USRJRN 附加到每个表的日志记录。
我怎样才能让我的脚本这样做呢?
我收到以下错误:
库 MYLIB 中文件 MYTABLE 的未提交更改挂起。
CPF325E
原因 。. . . . : 对于提交定义 MYTABLE,库 MYLIB 中的文件 MYTABLE 的未提交更改正在等待处理。
恢复 。. . :执行以下操作之一并再次尝试您的请求:
-- 通过对承诺定义 MYTABLE 进行提交或回滚来完成承诺控制过程。
-- 更改提交控制选项并重新编译程序。
技术说明 。. . . . . . . : 承诺定义标识符是 X'5CC4C6E3C1C3E3C7D9D7'。启动更改的作业是 954538/QUSER/QZDASOINIT。工作标识符的逻辑单元是*N。锁空间标识符是*N。The XID is X'5CD5404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040'.
问题是,954538/QUSER/QZDASOINIT 不是活动作业。它不会显示在活动作业下并运行此:
WRKCMTDFN 954538/QUSER/QZDASOINIT
给出了这个:
找不到作业 954538/QUSER/QZDASOINIT。
...怎么了?已完成的作业如何与待处理的更改相关联?如何回滚这些更改?
编辑:回答答案中的问题:
你在哪里看到的消息?
具体的情况是,在 System iNavigator 中,我右键单击 MYTABLE 并选择 Journaling。让我发现问题的原始错误是 C# 抛出:
iDB2SQLErrorException:MYLIB 类型 *FILE 中的 SQL0910 对象 MYTABLE 有一个挂起的更改。
同样,在尝试从 MYTABLE 中删除引用约束时,我收到“更改未决”错误。
你有 *JOBCTL 权限吗?可能是工作没有消失,只是你没有权限看到它。
不知道,也不知道怎么查。如果我运行:
WRKCMTDFN QUSER/QZDASOINIT
然后出现一堆工作,但 954538 不是其中之一。
如果相关,我正在使用 IBM i V7R1M0。
我在 C# 中有一些代码:
var generateSqlSql = $@"
CALL QSYS2.GENERATE_SQL(
'{obj.Name}',
'{obj.Library}',
'VIEW',
CREATE_OR_REPLACE_OPTION => '1',
HEADER_OPTION => '0',
COMMENT_OPTION => '1',
PRIVILEGES_OPTION => '0',
LABEL_OPTION => '0'
)";
...
//get results
//split on semicolon
//change library
//write back to database
然后它试图编写的 sql 是:
CREATE OR REPLACE VIEW AMMLIBC.BBI_USER_MY_VIEW FOR SYSTEM NAME BBIU_00001 (
/* view columns */ )
AS
/*view definition */
RCDFMT BBIU_00001
当我尝试运行它时,它会出现以下错误:
iDB2SQLErrorException: SQL7029 New name BBIU_00001 is not valid.
...为什么?是什么原因造成的,我该如何让它发挥作用?
考虑以下表结构:
UserGroup(ie. 'Admin')
ID = 'Admin'
ApplicationFK = 'App1'
JoinTable
UserGroupFK = 'Admin'
PermissionFK = 'Approve'
PermissionValue = 'READ'
Permission(ie. 'Approve')
ID = 'Approve'
ApplicationFK = 'App2'
UserPermission
UserFK = 'John'
PermissionFK = 'Approve'
PermissionValue = 'WRITE'
User
ID = 'John'
在 UserGroup 和 Permission 之间有一个可连接的地方,UserGroup 和 Permission 都有应用程序的外键。
有什么方法可以强制完整性,以避免出现上述 ApplicationFK 不匹配的情况?我不能简单地删除其中一个外键,因为可能有一个没有任何用户组的权限,也可能有一个没有任何权限的用户组。