MySQL : @ 변수와 변수 차이점이 뭐야?


501

다른 질문에 누군가가 게시 한 내용은 다음과 같은 차이점이 있습니다.

@variable

과:

variable

MySQL에서. 또한 MSSQL에 배치 범위가 있고 MySQL에 세션 범위가있는 방법에 대해서도 언급했습니다. 누군가 나를 위해 이것을 자세히 설명 할 수 있습니까?


1
나는 MsSQL에 익숙하므로 그런 질문을 결코하지 않았다. 여기에 제공된 대답은 내가 IDEA가없는 것에 나를 붙 잡았습니다! Thx ..
Ken

답변:


624

MySQL사용자 정의 변수 개념이 있습니다 .

이들은 세션 어딘가에서 초기화 될 수있는 느슨한 유형의 변수이며 세션이 끝날 때까지 값을 유지합니다.

다음과 같은 @부호 가 붙습니다 .@var

SET명령문으로 또는 쿼리 에서이 변수를 초기화 할 수 있습니다 .

SET @var = 1

SELECT @var2 := 2

에서 저장 프로 시저를 개발할 때 MySQL입력 매개 변수를 전달하고 로컬 변수를 선언 할 수 있습니다.

DELIMITER //

CREATE PROCEDURE prc_test (var INT)
BEGIN
    DECLARE  var2 INT;
    SET var2 = 1;
    SELECT  var2;
END;
//

DELIMITER ;

이러한 변수 앞에는 접두사가 붙지 않습니다.

프로 시저 변수와 세션 별 사용자 정의 변수의 차이점 NULL은 프로 시저가 호출 될 때마다 프로 시저 변수가 다시 초기화 되지만 세션 별 변수는 그렇지 않다는 것입니다.

CREATE PROCEDURE prc_test ()
BEGIN
    DECLARE var2 INT DEFAULT 1;
    SET var2 = var2 + 1;
    SET @var2 = @var2 + 1;
    SELECT  var2, @var2;
END;

SET @var2 = 1;

CALL prc_test();

var2  @var2
---   ---
2     2


CALL prc_test();

var2  @var2
---   ---
2     3


CALL prc_test();

var2  @var2
---   ---
2     4

보시다시피 var2, 프로 시저가 호출 될 때마다 (프로 시저 변수)가 초기화되고 @var2(세션 별 변수)는 초기화 되지 않습니다.

(MySQL 에는 사용자 정의 변수 외에도 미리 정의 된 "시스템 변수"가 있습니다 . 이러한 " 시스템 변수"는 "글로벌 변수"와 같은 @@global.port"세션 변수"와 같을 수 있습니다 @@session.sql_mode. 이러한 "세션 변수"는 세션 별 사용자 정의와 관련이 없습니다. 변수.)


43
또한 사용 가능한 전역 변수가 있습니다. SELECT @@version;예를 참조하십시오 . 이것은 또한 사용 DELIMITER @@이 실제로 좋은 생각이 아닌 이유이기도합니다 .
Mchl

13
그것은 새로 온 사람들에게 새로운 의문을 제기합니다 ... 귀하의 예와 같이 "var = var"와 "var : = var"사이에 차이점이 있습니까?
confiq

13
@confiq : 없습니다.
Quassnoi

10
새로 온 사람을위한 또 다른 질문. 언제 사용 @하지 않는 것이 좋 습니까?
pixelfreak 2018

73
@confiq, @Quassnoi : :=와 사이에는 한 가지 중요한 차이점 =이 있습니다. 즉 :=, 어디에서나 변수 할당 연산자로 =작동하는 반면 SET명령문에서는 그렇게 작동하고 다른 곳에서는 비교 연산자입니다. 따라서 SELECT @var = 1 + 1;@var을 변경하지 않고 부울 (@var의 현재 값에 따라 1 또는 0)을 SELECT @var := 1 + 1;반환하고 @var을 2로 변경하고 2를 반환합니다.
Dewi Morgan

71

MySQL에서는 사용자 정의 변수를@variable 나타냅니다 . 자신을 정의 할 수 있습니다.

SET @a = 'test';
SELECT @a;

저장된 프로그램 외부에서 variable, without @시스템 변수 이므로 직접 정의 할 수 없습니다.

이 변수의 범위는 전체 세션입니다. 이는 데이터베이스와의 연결이 존재하는 동안 변수를 계속 사용할 수 있음을 의미합니다.

이는 MSSQL과 달리 현재 쿼리 배치 (저장 프로 시저, 스크립트 또는 기타)에서만 변수를 사용할 수 있습니다. 동일한 세션에서 다른 배치로 사용할 수 없습니다.


2
축약 형 SET @@a = 'test';cf 를 가진 세션 변수와 혼동하지 마십시오. dev.mysql.com/doc/refman/5.1/en/set-statement.html
RobM

@RobM, 세션 변수가 아니라 시스템 변수 라고 합니다.
Pacerier

1
@Pacerier : 내가 문서를 잘못 읽고 있습니까? "" "변수가 세션 변수임을 명시 적으로 나타내려면 이름 앞에 SESSION, @@ session. 또는 @@." "
RobM

5
@RobM, 잘못 읽고 있습니다. 글 머리 기호 내의 단락 만이 아니라 전체 단락을 읽습니다. 간단히 말해 두 가지 종류의 세션 변수가 있습니다. 1) 사용자 정의 세션 변수 및 2) 시스템  정의 세션 변수. 을 사용하여 사용자 정의 세션 변수를 설정할 수 없습니다 @@. 예를 들어 set@@my_var=1, set@@session.my_var=1하고 set session my_var=1있기 때문에 작동하지 않을 것입니다 my_var하지 않은 것입니다 시스템 변수를 우리가 할 수있는 반면 set@@big_tables=1, set@@session.big_tables=1하고 set session big_tables=1있기 때문에 big_tables시스템 변수입니다.
Pacerier

1
@GovindRai :에서 Quassnoi의 대답은, var2없는 변수 @접두사하지만 시스템 변수되지 않습니다 : 그것은 프로 시저 변수입니다. 저장 프로 시저 (일명 저장 프로그램)에 있기 때문에 허용됩니다. 저장 프로 시저 이외의 변수 @는 시스템 변수입니다.
LarsH

10

MSSQL은 프로 시저 내의 변수가 DECLAREd이어야하고 사람들은 @Variable 구문 (DECLARE @TEXT VARCHAR (25) = 'text')을 사용해야합니다. 또한 MS는 맨 위에 모든 DECLARE가 필요한 mySQL과 달리 프로 시저의 모든 블록 내에서 선언을 허용합니다.

커맨드 라인에는 좋지만 mySQL의 저장 프로 시저 내에서 "set = @variable"을 사용하는 것이 위험하다고 생각합니다. 범위와 변수는 범위 경계에 없습니다. 이는 "var"접두사없이 선언 된 JavaScript의 변수와 유사합니다.이 변수는 전역 네임 스페이스이며 예기치 않은 충돌 및 덮어 쓰기를 생성합니다.

mySQL의 좋은 사람들이 DECLARE @Variable을 저장 프로 시저 내의 다양한 블록 수준에서 사용할 수 있기를 바랍니다. @ (기호)를 확인하십시오. @ 기호 접두사는 변수 이름을 테이블 열 이름과 구분하는 데 도움이됩니다. 물론, 항상 "v"또는 "l_"접두어를 추가 할 수 있지만 @ 기호는 변수 이름을 데이터를 추출하지 않고 열을 일치시키는 편리한 방법으로 간결한 방법입니다.

MySQL은 저장 프로 시저에 익숙하지 않으며 첫 번째 버전에서 훌륭한 작업을 수행했습니다. 그들이 어디에서 그것을 사용 하는지를보고 언어의 서버 측 측면이 성숙 해지는 것을 보는 것은 즐거움이 될 것입니다.


3

원칙적으로 저장 프로 시저 내에서 UserDefinedVariables (@ 앞에 추가)를 사용합니다. 이것은 특히 두 개 이상의 저장 프로 시저에서 이러한 변수가 필요할 때 삶을 더 쉽게 만듭니다. ONE 저장 프로 시저 내에서만 변수가 필요한 경우 시스템 변수를 사용하는 것 (앞에 @없이)을 사용하십시오.

@ Xybo : StoredProcedures에서 @variables를 사용하는 것이 위험한 이유를 이해하지 못합니다. "scope"와 "boundaries"를 조금 더 쉽게 설명해 주시겠습니까?


3
이는 기본 소프트웨어 엔지니어링 원칙을 위반합니다. 범위가 무엇인지, 그리고 전역 변수를 사용하는 것이 왜 끔찍한 아이디어인지 정확히 알 때까지 다른 코드 줄을 작성하지 마십시오. 101 개의 프로그래밍 클래스를 받았을 때 거의 모든 것을 위해 전역을 사용하는 것을 기억할 때 자동 "F"가 발생합니다. 특별한 예외가 있지만 일반적으로하지 마십시오!
BuvinJ

왜? -@Variables는 모든 MySQL-Book에서 절대적으로 일반적입니다.
피터

함수 호출, 프로 시저, 트리거 등이없는 "평평한"스크립트에서, 간단한 스크립트 또는 제한된 명령 세트를 실행 한 다음 세션을 종료하려면 (글로벌을 파괴 함) 확실합니다. 이 경우 원하는 경우 계속 사용하십시오. 그러나 함수 내에서 사용하지 마십시오! 단순히 Google 전역 변수 또는 범위를 사용하면 보편적으로 눈살을 찌푸 리다는 아이디어를 즉시 광범위하게 지원할 수 있습니다. 시작점이 있습니다 : wiki.c2.com/?GlobalVariablesAreBad 또는보다 일반적인 설명 : en.wikipedia.org/wiki/Global_variable
BuvinJ

2
MySQL에서 @variables는 전역 적입니다. 이것은 쉽게 확인됩니다. 함수 외부에 하나를 설정하고 함수 내부에 평가하십시오. 반대로 함수 내부를 설정하고 함수 외부에서 평가하십시오. 기능이 그러한 범위를 보호하지 않는 것을 볼 수 있습니다. 그들은 서로의 발가락을 밟습니다.
BuvinJ

1
MySQL 용어를 사용하면 @@GLOBAL변수가 훨씬 "전역 적으로"교활합니다. 그들은 세션을 교차! @variables"세션 범위"를 가지므로 적어도 그들은 그런 식으로 제한되어 있습니다. 그러나 "전역"범위라고 부르는 모든 일반 언어 (기능을 교차하는 경우). "글로벌"의 MySQL 개념은 아마도 "유니버설 (universal)"이라고 불려야한다. 이는 그것이 실행되는 프로세스의 경계를 넘어서 확장된다는 점이다. 프로세스는 메모리 공간을 공유하지 않기 때문에 "글로벌"은 표준 언어로이를 수행 할 수 없습니다. 이는 SQL의 지속적 (휘발성) 경향에서 비롯됩니다.
BuvinJ
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.