我在NodeJS依赖环境中使用版本"mysql": "^2.16.0",
的mysql。
目标sql数据库是5.7.10版的mariaDB。
假定2个表共享同一列itemID
,第一个表名称为dol_gameItems
,第二个表名称为dol_gameItemConsumableProperties
。
假设任何表的itemID中都没有NULL值,并且dol_gameItemConsumableProperties
中匹配项的数量小于dol_gameItems
中的匹配项。
假设查询在列上执行左连接
select t1.itemID
from dol_gameItems t1
left join dol_gameItemConsumableProperties t2
on t1.itemID=t2.itemID
limit 2;
如果以上查询是在终端中执行的,则结果为(如预期的那样):
+--------+
| itemID |
+--------+
| 1 |
| 2 |
(itemID为有效数字,即使与其他表不匹配,也不为空)
如果我们执行以下查询
select t2.itemID
from dol_gameItems t1
left join dol_gameItemConsumableProperties t2
on t1.itemID=t2.itemID
limit 2;
我们从第二个联接表中获取NULL值(根据左联接的定义,我知道这是可以的)
+--------+
| itemID |
+--------+
| NULL |
| NULL |
+--------+
如果我们执行
select itemID
from dol_gameItems t1
left join dol_gameItemConsumableProperties t2
on t1.itemID=t2.itemID
limit 2;
我们得到了模糊的列错误,这也是预期的。
但是,如果我使用mysql在NodeJS中执行以下查询:
let ITEMS_T: string = DbsConstModel.getTableName(DbsConstModel.itemsJSON);
let ITEM_ID: string = DbsConstModel.getTableColumnName(DbsConstModel.itemsJSON, 'ITEM_ID');
let CONS_PROPERTIES_T: string = DbsConstModel.getTableName(DbsConstModel.itemConsumablePropertiesJSON);
var q = `select *, t1.${ITEM_ID} from ${ITEMS_T} t1 left join ${CONS_PROPERTIES_T} t2 on t1.${ITEM_ID}=t2.${ITEM_ID}`;
var self = this;
this.dbs.connection.query(q,
[],
function(err, res) {
if (err) throw err;
//key is item ID, value is dao
var list = new HashMap<string, ItemBaseDAO>();
//console.log("got " + res.length + "results")
for (let i = 0; i < res.length; i++) {
console.log(res[i][ITEM_ID]);
//and so on....
然后,如果两个表都匹配itemID,则itemID中的结果是正确的数字,否则为NULL。
这违反了SQL的法则。我对此的唯一解释是,模块(javascript mysql)看到2个相同的列,并以某种方式合并它们,如果其中任何一个为NULL,则产生NULL。
如果我打印出原始数据包,我确实在那找到了空值:
console.log(res[i]);
RowDataPacket {
itemID: null,
tag: '',
equipmentSlot: -1,
inventorySizeX: 1,
inventorySizeY: 1,
.
.
.
}
(没有t1.itemID变量,只有itemID。由于有50多列,我切断了输出。)
但是,解决方案是创建别名
var q = `select *, t1.${ITEM_ID} as itemIdAlias from ${ITEMS_T} t1 left join ${CONS_PROPERTIES_T} t2 on t1.${ITEM_ID}=t2.${ITEM_ID}`;
并要求别名
console.log(res[i]['itemIdAlias']);
产生正确的itemID号,没有NULL。 但是,我发现这种行为很奇怪,解决方案代码有点不干净。但是,我无法弄清这种奇怪行为的原因。有没有人经历过这种行为并知道为什么会发生?