【问题标题】:What is the correct syntax for passing a static string with a select query?使用选择查询传递静态字符串的正确语法是什么?
【发布时间】:2017-02-12 06:15:13
【问题描述】:

这是我在 Yii 控制器中的查询。我正在尝试将控制器的名称作为静态字符串传递。此语法会引发错误

“关键字 LEFT 附近的语法不正确。”

如果我使用:

'Message' AS controllerName,

...然后它工作正常。

完整功能:

/**
 * Datatable: Message
 *
 * @param $status
 */
public function actionMessage($status) {
    // only allow ajax requests to this action
    if (!Yii::app()->request->isAjaxRequest && !YII_DEBUG) {
        Yii::app()->end();
    }

    // start building the create command
    $command = Yii::app()->db->createCommand()
        ->select("
            {Yii::app()->controller->id} AS controllerName,
            Message.MessageID AS primaryKey,
            Message.Name AS messageName,
            Message.Code AS messageCode,
            Message.CloneOf AS messageCloneOf,
            Message.IsActive AS messageIsActive,
            Message.IsArchived,
            Client.Name AS clientName,
            Workflow.WorkflowID AS workflowID,
            Workflow.Name AS workflowName,
            Workflow.Color AS workflowColor,

            STUFF((
                SELECT CAST(',' + aprv AS VARCHAR(MAX))
                FROM
                    (
                        SELECT MessageID, mv.RowInsertDate AS inDate, CONCAT(REPLACE(SUBSTRING ( a.Options ,0 , PATINDEX('%\",\"required\"%', a.Options )),'{\"name\":\"',' '), ' - All - ', CONCAT(u.FirstName,' ',u.LastName), ' on ' , mv.RowInsertDate) AS aprv
                            FROM MessageApproval mv
                            JOIN [User] u ON u.UserID = mv.UserID
                            JOIN [Action] a ON a.ActionID = mv.ActionID
                            WHERE mv.IsApproved=1
                        UNION
                        SELECT MessageID, mvl.RowInsertDate AS inDate, CONCAT(REPLACE(SUBSTRING ( a.Options ,0 , PATINDEX('%\",\"required\"%', a.Options )),'{\"name\":\"',' '), ' - ', l.Code, ' - ', CONCAT(u.FirstName,' ',u.LastName), ' on ' , mvl.RowInsertDate) AS aprv
                            FROM MessageApprovalLocale mvl
                            JOIN [User] u ON u.UserID = mvl.UserID
                            JOIN Locale l ON l.LocaleID = mvl.LocaleID
                            JOIN [Action] a ON a.ActionID = mvl.ActionID
                            WHERE mvl.IsApproved=1
                    ) AS approvalData
                WHERE (Message.MessageID = approvalData.MessageID)
                ORDER BY inDate DESC
            FOR XML PATH ('')), 1, 1, '') AS Approvals,

            STUFF((SELECT CAST(',' + [Name] AS VARCHAR(MAX))
            FROM [Brand]
            JOIN MessageBrand ON Brand.BrandID = MessageBrand.BrandID
            WHERE (Message.MessageID = MessageBrand.MessageID)
            ORDER BY Brand.Name ASC
            FOR XML PATH ('')), 1, 1, '') AS brands,

            STUFF((SELECT CAST(',' + [Name] AS VARCHAR(MAX))
            FROM [Communication]
            JOIN CommunicationRegionMessage ON Communication.CommunicationID = CommunicationRegionMessage.CommunicationID
            WHERE (Message.MessageID = CommunicationRegionMessage.MessageID)
            ORDER BY Communication.Name ASC
            FOR XML PATH ('')), 1, 1, '') AS communications,

            STUFF((SELECT CAST(',' + [Name] AS VARCHAR(MAX))
            FROM [Track]
            JOIN TrackCommunication ON Track.TrackID = TrackCommunication.TrackID
            JOIN CommunicationRegionMessage ON TrackCommunication.CommunicationID = CommunicationRegionMessage.CommunicationID
            WHERE (Message.MessageID = CommunicationRegionMessage.MessageID)
            ORDER BY Track.Name ASC
            FOR XML PATH ('')), 1, 1, '') AS tracks,

            STUFF((SELECT CAST(',' + [Name] AS VARCHAR(MAX))
            FROM [Series]
            JOIN SeriesTrack ON Series.SeriesID = SeriesTrack.SeriesID
            JOIN TrackCommunication ON SeriesTrack.TrackID = TrackCommunication.TrackID
            JOIN CommunicationRegionMessage ON TrackCommunication.CommunicationID = CommunicationRegionMessage.CommunicationID
            WHERE (Message.MessageID = CommunicationRegionMessage.MessageID)
            ORDER BY Series.Name ASC
            FOR XML PATH ('')), 1, 1, '') AS series,

            STUFF((SELECT CAST(',' + [Name] AS VARCHAR(MAX))
            FROM [Campaign]
            JOIN CampaignSeries ON Campaign.CampaignID = CampaignSeries.CampaignID
            JOIN SeriesTrack ON CampaignSeries.SeriesID = SeriesTrack.SeriesID
            JOIN TrackCommunication ON SeriesTrack.TrackID = TrackCommunication.TrackID
            JOIN CommunicationRegionMessage ON TrackCommunication.CommunicationID = CommunicationRegionMessage.CommunicationID
            WHERE (Message.MessageID = CommunicationRegionMessage.MessageID)
            ORDER BY Campaign.Name ASC
            FOR XML PATH ('')), 1, 1, '') AS campaigns,

            STUFF((SELECT CAST(',' + [Name] AS VARCHAR(MAX))
            FROM [Program]
            JOIN MessageProgram ON Program.ProgramID = MessageProgram.ProgramID
            WHERE (Message.MessageID = MessageProgram.MessageID)
            ORDER BY Program.Name ASC
            FOR XML PATH ('')), 1, 1, '') AS programs,

            STUFF((SELECT '|' + Name + ';' + CAST(Template.RowUpdateDate AS VARCHAR)
            FROM [Template]
            JOIN MessageTemplate ON Template.TemplateID = MessageTemplate.TemplateID
            WHERE (Message.MessageID = MessageTemplate.MessageID)
            ORDER BY Template.Name ASC
            FOR XML PATH ('')), 1, 1, '') AS templates,

            STUFF((SELECT CAST(',' + [Code] AS VARCHAR(MAX))
            FROM [Template]
            JOIN MessageTemplate ON Template.TemplateID = MessageTemplate.TemplateID
            WHERE (Message.MessageID = MessageTemplate.MessageID)
            ORDER BY Template.Name ASC
            FOR XML PATH ('')), 1, 1, '') AS templateCodes,

            STUFF((SELECT DISTINCT ',' + CAST([Name] AS VARCHAR(MAX))
            FROM [Connector]
            JOIN PublishMessage ON Connector.ConnectorID = PublishMessage.ConnectorID
            WHERE (Message.MessageID = PublishMessage.MessageID)
            FOR XML PATH ('')), 1, 1, '') AS pubConnectors,

            PublishMessage.PublishStartDate AS pubStart,
            PublishMessage.PublishEndDate AS pubEnd,
            PublishMessage.PublishID AS pubID,

            STUFF((
                SELECT '|' + CAST(CONCAT(IsPublished,'.',Code,'.',SUBSTRING(PublishResponse, 0, 20)) AS VARCHAR)
                    FROM PublishMessage
                    JOIN (
                        SELECT MAX(Publish.PublishID) PublishID, MAX(PublishMessage.PublishMessageID) PublishMessageID, MAX(PublishMessage.MessageID) MessageID, Locale.Code, MAX(Publish.RowInsertDate) RowInsertDate
                        FROM Publish
                        JOIN Locale ON Locale.LocaleID=Publish.LocaleID
                        JOIN PublishMessage ON PublishMessage.PublishID = Publish.PublishID
                        WHERE MessageID=Message.MessageID
                        GROUP BY Locale.Code
                    ) AS latest ON latest.PublishMessageID=PublishMessage.PublishMessageID
                    ORDER BY IsPublished DESC, PublishMessage.RowInsertDate DESC
                FOR XML PATH ('')
            ), 1, 1, '') AS pubStatus,

            PublishMessage.PublishResponse AS pubResponse,
            STUFF((SELECT '|' + MetaName + ':=' + MetaValue FROM ConnectorDetail WHERE ConnectorID = Connector.ConnectorID AND Show = 1 FOR XML PATH('')), 1, 1, '') as pubMeta
        ")
        ->from('Message')
        ->leftJoin('PublishMessage', 'PublishMessage.PublishMessageID = (SELECT MAX(PublishMessageID) FROM PublishMessage WHERE PublishMessage.MessageID = Message.MessageID AND PublishStartDate IS NOT NULL)')
        ->leftJoin('Connector', 'Connector.ConnectorID = PublishMessage.ConnectorID')
        ->join('Workflow', 'Message.WorkflowID = Workflow.WorkflowID')
        ->join('Client', 'Client.ClientID = Message.ClientID')
        ->where(DBHelper::whereFilterUserClient())
        ->order('Message.Name ASC');

    // apply status filter
    switch ($status) {
        case 'all':
            $command->andWhere('Message.IsArchived = 0');
            break;
        case 'archive':
            $command->andWhere('Message.IsArchived = 1');
            break;
        default:
            Yii::app()->end(sprintf('Invalid Status: %s', $status));
    }

    // get the query result
    $data = $command->queryAll();

    // Add in unapproved locales to the approvals (I couldn't find an efficient way to include this in main query)
    $localeApprovalMsgIDs = array_keys(MessageApprovalLocale::usesLocaleApproval());
    $unapprovedLocales = MessageApprovalLocale::unApprovedLocales($localeApprovalMsgIDs);

    foreach ($data as &$message) {

        if ( isset($unapprovedLocales[$message['primaryKey']]) ) {
            $message['Approvals'] = trim($message['Approvals'] . ',' . $unapprovedLocales[$message['primaryKey']]['Locales'],',');
        }
    }

    TableHelper::actionDataTable($data, $status == 'all' ? $this->dataTableColumns() : array_slice($this->dataTableColumns(), 2));
}

【问题讨论】:

  • 请将抛出的错误添加到问题中。请将您正在使用的 SQL 变体添加到问题中。请在您的示例有问题的代码中添加足够的内容,以使左括号“(”与右括号“)”配对。根据代码 sn-p,我无法判断您的代码是像 ...->select("... from table") 还是像 ...->select("...") from table
  • 尝试 var_dump 查询生成的 rowsql var_dump($command->sql) 以便查看有效执行的 sql 命令。
  • 它没有完成命令,那么我应该在哪里放置 var_dump 语句?这个特殊的功能已经顺利运行了相当长的一段时间。我只添加了一行来打破它。
  • 该命令在调用 $command->queryAll() 时执行...但是由 createCommand 构建而不执行...所以您应该使用命令获取 sql 代码 ..var_dump($command ->sql)
  • 啊哈!感谢您的信息。

标签: php sql yii static yii2


【解决方案1】:

你必须为此使用参数绑定:

$command = Yii::app()->db->createCommand()
    ->select("
        :controllerid AS controllerName,

...

->order('Message.Name ASC')
->bindParam(':controllerid', Yii::$app->controller->id);

【讨论】:

    猜你喜欢
    • 2011-10-05
    • 1970-01-01
    • 2011-12-12
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    相关资源
    最近更新 更多