web-dev-qa-db-ja.com

パラメータ付きのビュー、それは可能ですか?

私はPHP=アプリケーションで作業しており、いくつかの「複雑な」クエリがコードに表示され始めています。複雑なため、ORMを使用できません。唯一のリソースはプレーンSQLとPHP MySQLネイティブ関数は好きではありません。

これ以上ない場合、ビューに変換したいクエリの1つがあります。

SELECT
  COUNT(*) AS 'rec',
  CONCAT(
      IF(agreement_list.ActiveFlag, '', 'Agreement is Inactive.'),
      IF(agreement_type.ActiveFlag, '', 'Agreement Type is Inactive.'),
      IF(distributor.ActiveFlag, '', 'License Distributor is InActive.'),
      IF(agreement_distributor.ActiveFlag, '', 'Agreement Distributor is InActive.'),
      IF(customer.ActiveFlag, '', 'Customer is Inactive.'),
      IF(cf_program_level.ActiveFlag, '', 'Program Level is Inactive.')
  ) AS errormessage,
  IF((agreement_list.ActiveFlag + agreement_type.ActiveFlag + distributor.ActiveFlag + agreement_distributor.ActiveFlag + customer.ActiveFlag + cf_program_level.ActiveFlag) < 6, 1, 0 ) AS error
FROM
  license
  JOIN agreement_list ON (agreement_list.AgreementTypeID = license.AgreementTypeID AND agreement_list.CustomerSiteID = license.CustomerSiteID AND agreement_list.Source = license.Source)
  JOIN customer ON (customer.id = license.CustomerSiteID AND license.source = customer.Source)
  JOIN distributor ON (distributor.DistributorID = license.DistributorID AND license.source = distributor.Source)
  JOIN distributor AS agreement_distributor ON (agreement_distributor.DistributorID = agreement_list.DistributorID AND agreement_list.source = agreement_distributor.Source)
  JOIN agreement_type ON (agreement_type.AgreementTypeID = license.AgreementTypeID AND license.source = agreement_type.Source)
  JOIN cf_program_level ON (cf_program_level.CFProgramLevelID = '{$CFProgramLevelID}' AND license.source = cf_program_level.Source)
WHERE
  license.AgreementTypeID = '{$AgreementTypeID}'
  AND license.CustomerSiteID = '{$CustomerSiteID}'
  AND license.Source = '{$Source}'

$CFProgramLevelID, $AgreementTypeID, $CustomerSiteID, $Sourceは、PHP=からのパラメーターであり、それが私の唯一の問題です。可能であれば、ビューにパラメーターを渡すにはどうすればよいですか?

現在、MySQL 5.6を使用しています。

3
ReynierPM

シンプルに思えます。最後の5行なしでVIEWをビルドします。次に、VIEWTABLEであるかのように使用するときに、これらの5行を使用します。

それらのJOINsが "many:one"でない場合、膨らんだCOUNT(*)を取得します。

2
Rick James

さらに良いことに、セッション変数から値を取得する関数を作成することで、簡単な方法でパラメーターをビューに渡すことができます。
手法については、www.stackoverflow.com/questions/14511760を参照してください。これは、後でパターン化したい私の作成関数のコピーです。

DELIMITER //

CREATE FUNCTION fn_getcase_id()    
RETURNS MEDIUMINT(11)
DETERMINISTIC NO SQL
BEGIN
# see stackoverflow.com/questions/14511760 and read ALL the info TWICE or MORE.  wh 04/13/2017
    RETURN @sv_case_id;
END//

DELIMITER ;

同様のFNを4つ作成する必要があります(変数ごとに1つ)。

2
Wilson Hauck

できません。少なくとも直接ではない。一時テーブルにデータを入力するプロシージャを使用して、コードでテーブルを参照します。

0
jfroebe

機能的な代替案は、パラメーターを渡して、ビュークエリをプロシージャにカプセル化することです。これは、複数のテーブル間の複数の結合クエリでVIEWSが遅いという問題を改善する簡単なソリューションです。

DELIMITER ;;
CREATE PROCEDURE `SP_QUERY_VIEW_WITH_PARAMETERS`(IN p_having VARCHAR(300))
    COMMENT 'Executes the statement'
BEGIN
  SET @v_having = p_having;
  SET @v_sql=CONCAT('SELECT 
                    id    AS id_emp  ,
                    user  AS emp_name,
                    .
                    .
                    .
                    FROM table1
                    UNION ALL
                    SELECT 
                    idtifier_us    AS id_emp  ,
                    description    AS emp_name,
                    .
                    .
                    .
                    FROM table2');
SET @v_sql2 = CONCAT(@v_sql,@v_having);
  PREPARE stmt FROM @v_sql2;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END ;;
DELIMITER ;


CALL `SP_QUERY_VIEW_WITH_PARAMETERS`('having id_emp=63 and emp_name like ''VANDERLEI%'' and created_at between ''2019-05-01'' and ''2019-05-17''  ')