另一个“#1054:“字段列表”中的未知列”之谜

时间:2019-12-02 23:02:49

标签: mysql mysql-error-1054

寻找任何解决方案,但未成功... 神秘之处在于我的一些功能。我在下面介绍了其中两个。它们基本相同,但Fun1可以正常工作,而Fun2则不能。该错误与主题-““字段列表”中的未知列”相同。我注意到,它取决于声明的变量类型-如果它是字符串(如tadnotation),则不会遇到问题,如果它是时间,十进制,枚举,则会导致错误。有人可以向我解释吗?当然,我也在寻找解决方案,因此欢迎大家提出建议。

每个功能的输入均相同:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os, sys
import pytest

from PyQt5 import QtGui, QtCore, QtWidgets, QtTest
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QCoreApplication, Qt, QObject

from pytestqt.plugin import QtBot

GUI = __import__('GUI')


@pytest.yield_fixture(scope="module")
def qtbot_session(qapp, request):
    print("  SETUP qtbot")
    result = QtBot(qapp)
    with capture_exceptions() as exceptions:
        yield result
    print("  TEARDOWN qtbot")


@pytest.fixture(scope="module")
def Viewer(request):
    print("  SETUP GUI")
    app, imageViewer = GUI.main_GUI()
    qtbotbis = QtBot(app)
    # qtbotbis.addWidget(imageViewer)
    # qtbotbis.wait_for_window_shown(imageViewer)
    QtTest.QTest.qWait(0.5 *1000)
    yield app, imageViewer, qtbotbis

    # EXIT
    # mocker.patch.object(QMessageBox, 'question', return_value=QMessageBox.Yes)
    # imageViewer.toolb_action_Exit.trigger()
    def handle_dialog():
        # while not imageViewer.replyClosing.isVisible():
        #   app.processEvents()
        box = QMessageBox()
        box.setStandardButtons(QMessageBox.Yes)
        button = box.button(QMessageBox.Yes)
        qtbotbis.mouseClick(button, QtCore.Qt.LeftButton)
    QtCore.QTimer.singleShot(100, handle_dialog)
    qtbotbis.mouseClick(imageViewer.btn_quit, QtCore.Qt.LeftButton, delay=1)
    assert imageViewer.close()
    print("  TEARDOWN GUI")


class Test_GUI() :
    def test_interface(self, Viewer):
        print("  beginning ")
        app, imageViewer, qtbot = Viewer
        qtbot.mouseClick( imageViewer.btn_prt, QtCore.Qt.LeftButton )
        QtTest.QTest.qWait(0.5 *1000)
        assert True
        print(" Test passed")

Fun1:

(`vtable` ENUM('user','client', 'daily_operation','monthly_operation'), 
`vclient_id` SMALLINT,
`vuser_id` SMALLINT, 
`vid` INT,
`vedition_id` TINYINT)

Fun2:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` FUNCTION `getAdnotation` (`vtable` ENUM('user', 'client', 'daily_operation', 'monthly_operation'), `vclient_id` SMALLINT, `vuser_id` SMALLINT, `vid` INT, `vedition_id` TINYINT) RETURNS TINYTEXT CHARSET utf8
BEGIN

DECLARE tadnotation TINYTEXT;

SET @tadnotation = CASE
    WHEN vtable = 'daily_operation' THEN 
        (SELECT adnotation FROM daily_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1)
    WHEN vtable = 'monthly_operation' THEN 
        (SELECT adnotation FROM monthly_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1)
END;
RETURN @tadnotation;

END$$

表(只有“ daily_operation”,因为“ monthly_operation”相似):

DELIMITER $$

CREATE DEFINER=`root`@`localhost` FUNCTION `getStartTime` (`vtable` ENUM('user', 'client', 'daily_operation', 'monthly_operation'), `vclient_id` SMALLINT, `vuser_id` SMALLINT, `vid` INT, `vedition_id` TINYINT) RETURNS TIME
BEGIN

DECLARE tstart_time TIME;

SET @tstart_time = CASE
    WHEN vtable = 'daily_operation' THEN 
        (SELECT start_time FROM daily_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1)
    WHEN vtable = 'monthly_operation' THEN 
        (SELECT start_time FROM monthly_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1)
END;
RETURN @tstart_time;

END$$

有效的是,如果我用以下方式更改SET-CASE子句:

CREATE TABLE `daily_operation` (
  `client_id` smallint(6) NOT NULL,
  `user_id` smallint(6) NOT NULL,
  `id` int(11) NOT NULL,
  `edition_id` tinyint(4) NOT NULL,
  `start_time` time NOT NULL,
  `end_time` time NOT NULL,
  `duration_minutes` smallint(6) NOT NULL,
  `duration_hours` decimal(4,2) NOT NULL,
  `adnotation` tinytext
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1 个答案:

答案 0 :(得分:0)

对我来说,CASE expression的分配有点令人困惑(难以阅读),因此我将CASE clause 与INTO @var 结合使用:

BEGIN
CASE
    WHEN vtable = 'daily_operation' THEN 
        SELECT start_time INTO @result FROM daily_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1;
    WHEN vtable = 'monthly_operation' THEN 
        SELECT start_time INTO @result FROM monthly_operation WHERE (client_id = vclient_id AND user_id = vuser_id AND id = vid AND edition_id = vedition_id) LIMIT 1;
END CASE;

RETURN @result;
END

注意,您不需要对SP中使用的@session_variables进行DECLARE。