私はこのようなビューを持っています:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = 2;
2を変数に変更することを意味します。私はこれを試しました:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = @MyVariable;
しかし、MySQLはこれを許可していません。
私はugい回避策を見つけました:
CREATE FUNCTION GetMyVariable() RETURNS INTEGER DETERMINISTIC NO SQL
BEGIN RETURN @MyVariable; END|
そして、ビューは次のとおりです。
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = GetMyVariable();
しかし、それは本当にくだらないように見え、使用法もまたくだらないです。ビューを使用するたびに@MyVariableを設定する必要があります。
私はこのように使用できる解決策があります:
SELECT Column FROM MyView(2) WHERE (...)
具体的な状況は次のとおりです。拒否されたリクエストに関する情報を格納するテーブルがあります。
CREATE TABLE Denial
(
Id INTEGER UNSIGNED AUTO_INCREMENT,
PRIMARY KEY(Id),
DateTime DATETIME NOT NULL,
FeatureId MEDIUMINT UNSIGNED NOT NULL,
FOREIGN KEY (FeatureId)
REFERENCES Feature (Id)
ON UPDATE CASCADE ON DELETE RESTRICT,
UserHostId MEDIUMINT UNSIGNED NOT NULL,
FOREIGN KEY (UserHostId)
REFERENCES UserHost (Id)
ON UPDATE CASCADE ON DELETE RESTRICT,
Multiplicity MEDIUMINT UNSIGNED NOT NULL DEFAULT 1,
UNIQUE INDEX DenialIndex (FeatureId, DateTime, UserHostId)
) ENGINE = InnoDB;
多重度とは、同じ秒に記録される多数の同一の要求です。拒否のリストを表示したいのですが、アプリケーションが拒否されると、念のため数回再試行します。そのため、通常、同じユーザーが同じ機能を数秒間で3回拒否すると、実際には1つの拒否になります。この要求を満たすためにもう1つのリソースがある場合、次の2つの拒否は発生しません。そのため、レポートで拒否をグループ化して、ユーザーが拒否をグループ化する期間を指定できるようにします。例えば。タイムスタンプに拒否(機能1のユーザー1)があり、ユーザーが4秒よりも互いに近い拒否をグループ化する場合、次のようになります。 (x2)、24(x3)、45(x1)。実際の拒否間の間隔は、複製間の間隔よりもはるかに大きいと想定できます。次の方法で問題を解決しました。
CREATE FUNCTION GetDenialMergingTime()
RETURNS INTEGER UNSIGNED
DETERMINISTIC NO SQL
BEGIN
IF ISNULL(@DenialMergingTime) THEN
RETURN 0;
ELSE
RETURN @DenialMergingTime;
END IF;
END|
CREATE VIEW MergedDenialsViewHelper AS
SELECT MIN(Second.DateTime) AS GroupTime,
First.FeatureId,
First.UserHostId,
SUM(Second.Multiplicity) AS MultiplicitySum
FROM Denial AS First
JOIN Denial AS Second
ON First.FeatureId = Second.FeatureId
AND First.UserHostId = Second.UserHostId
AND First.DateTime >= Second.DateTime
AND First.DateTime - Second.DateTime < GetDenialMergingTime()
GROUP BY First.DateTime, First.FeatureId, First.UserHostId, First.Licenses;
CREATE VIEW MergedDenials AS
SELECT GroupTime,
FeatureId,
UserHostId,
MAX(MultiplicitySum) AS MultiplicitySum
FROM MergedDenialsViewHelper
GROUP BY GroupTime, FeatureId, UserHostId;
次に、5秒ごとにマージされた機能3および4でユーザー1および2からの拒否を表示するには、次の操作を行うだけです。
SET @DenialMergingTime := 5;
SELECT GroupTime, FeatureId, UserHostId, MultiplicitySum FROM MergedDenials WHERE UserHostId IN (1, 2) AND FeatureId IN (3, 4);
ビューを使用するのは、データをフィルタリングし、jQueryグリッドで明示的に使用し、自動的に順序付けし、レコードの数を制限するなどが簡単だからです。
しかし、それは単なるい回避策です。これを行う適切な方法はありますか?
実際にfuncを作成する場合:
create function p1() returns INTEGER DETERMINISTIC NO SQL return @p1;
および表示:
create view h_parm as
select * from sw_hardware_big where unit_id = p1() ;
次に、パラメーターを指定してビューを呼び出すことができます。
select s.* from (select @p1:=12 p) parm , h_parm s;
役に立てば幸いです。
CREATE VIEW MyView AS
SELECT Column, Value FROM Table;
SELECT Column FROM MyView WHERE Value = 1;
MySQLの適切なソリューションです。他のSQLを使用すると、ビューをより正確に定義できます。
注:ビューが非常に複雑でない限り、MySQLはこれを最適に最適化します。
以前、ストアドプロシージャを使用せず、代わりにパラメーターテーブルといくつかのconnection_id()マジックを使用する別の回避策を思いつきました。
編集(コメントからコピー)
_connection_id
_という列を含むテーブルを作成します(bigintにします)。ビューのパラメーターの列をそのテーブルに配置します。 _connection_id
_に主キーを配置します。パラメータテーブルに置き換え、CONNECTION_ID()
を使用してconnection_id値を設定します。ビューで、パラメーターテーブルへのクロス結合を使用し、WHERE param_table.connection_id = CONNECTION_ID()
を配置します。これにより、パラメータテーブルの1つの行のみを使用したクロス結合が可能になります。その後、where句の他の列を使用できます(たとえば、where _orders.order_id = param_table.order_id
_)。