[mysql] MySQL에서 매개 변수로 뷰를 생성 할 수 있습니까?

다음과 같은 견해가 있습니다.

CREATE VIEW MyView AS
   SELECT Column FROM Table WHERE Value = 2;

더 일반적으로 만들고 싶습니다. 2를 변수로 변경하는 것을 의미합니다. 나는 이것을 시도했다 :

CREATE VIEW MyView AS
   SELECT Column FROM Table WHERE Value = @MyVariable;

그러나 MySQL은 이것을 허용하지 않습니다.

추악한 해결 방법을 찾았습니다.

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,2,24,26,27,45에 거부 (기능 1의 사용자 1에 대해)가 있고 사용자가 4 초보다 더 가까운 거부를 그룹화하려는 경우 다음과 같은 결과가 표시됩니다. 1 (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(). 이것은 당신이 원하는 매개 변수 테이블의 한 행과 만 교차 결합합니다. 그런 다음 where 절의 다른 열을 사용할 수 있습니다 (예 : where) orders.order_id = param_table.order_id.


답변