MySQL: @ değişkenli veya değişken. Fark ne?


501

Bir başka soruda, birisi arasında bana bir fark olduğunu söylediğini gönderdim:

@variable

ve:

variable

MySQL. Ayrıca MSSQL'in toplu kapsamı ve MySQL'in oturum kapsamı olduğunu belirtti. Birisi benim için bu konuyu açıklayabilir mi?


1
MsSQL'e aşinayım ve bu yüzden böyle bir soru sormak bana hiç şaşmadı. Burada verilen cevaplar hakkında hiçbir fikrim yoktu bir şey bana ipucu !! Teşekkürler ..
Ken

Yanıtlar:


624

MySQLkullanıcı tanımlı değişkenler kavramına sahiptir .

Bunlar, oturumun herhangi bir yerinde başlatılabilecek ve oturum sona erene kadar değerlerini koruyabilecek gevşek yazılan değişkenlerdir.

Bu gibi bir @işaret ile eklenirler :@var

Bu değişkeni SETbir sorguda veya bir sorguda içeride başlatabilirsiniz :

SET @var = 1

SELECT @var2 := 2

Bir saklı yordam geliştirdiğinizde MySQL, giriş parametrelerini iletebilir ve yerel değişkenleri bildirebilirsiniz:

DELIMITER //

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

DELIMITER ;

Bu değişkenlere herhangi bir önek eklenmez.

Bir yordam değişkeni ile oturuma özgü bir kullanıcı tanımlı değişken arasındaki fark, yordam değişkeninin NULLyordam her çağrıldığında yeniden başlatılmasıdır, oysa oturuma özgü değişken değildir:

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

Gördüğünüz gibi var2, prosedür her çağrıldığında (yordam değişkeni) yeniden başlatılırken @var2(oturuma özgü değişken) başlatılmaz .

(Kullanıcı tanımlı değişkenlere ek olarak, MySQL'in önceden tanımlanmış bazı "sistem değişkenleri" de vardır; bunlar "global değişkenler" gibi @@global.portveya "oturum değişkenleri" gibi @@session.sql_mode; bu "oturum değişkenleri", oturuma özgü kullanıcı tanımlı değildir değişkenler.)


43
Ayrıca, genel değişkenlerin mevcut olduğuna dikkat edin: SELECT @@version;Örneğin, bkz . Bu da kullanmanın neden DELIMITER @@iyi bir fikir olmadığının bir nedenidir .
Mchl

13
yeni sonuçlar için yeni sorular soruyor ... örneğinizde olduğu gibi "var = var" ve "var: = var" arasında herhangi bir fark var mı?
confiq

13
@confiq: Hiç yok.
Quassnoi

10
Yeni gelen için başka bir soru. @Vs not kullanılması ne zaman önerilir ?
pixelfreak

73
@confiq, @Quassnoi: :=ve arasında önemli bir fark vardır =ve bu :=her yerde değişken atama operatörü olarak =çalışır , ancak SETifadelerde bu şekilde çalışır ve başka her yerde bir karşılaştırma operatörüdür. Yani SELECT @var = 1 + 1;değişmeden @var ayrılıp ederken, (@ VAR şimdiki değerine bağlı olarak 1 veya 0) bir boolean dönecektir SELECT @var := 1 + 1;2'ye @var değişecek ve 2. return
Dewi Morgan

71

MySQL'de, @variable kullanıcı tanımlı bir değişkeni belirtir . Kendinizi tanımlayabilirsiniz.

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

Depolanan programların dışında, a variable, olmadan @, kendinizi tanımlayamayacağınız bir sistem değişkenidir .

Bu değişkenin kapsamı tüm oturumdur. Bu, veritabanıyla bağlantınız varken değişkenin hala kullanılabileceği anlamına gelir.

Bu, değişkenin yalnızca geçerli sorgu kümesinde (saklı yordam, komut dosyası veya başka bir şekilde) kullanılabileceği MSSQL'in tersidir. Aynı oturumda farklı bir grupta kullanılamaz.


2
Steno olan oturum değişkenleri ile karıştırılmamalıdır SET @@a = 'test';, bkz. dev.mysql.com/doc/refman/5.1/en/set-statement.html
RobM

@RobM, Bunlara oturum değişkenleri değil sistem değişkenleri denir .
Pacerier

1
@ Pacer: Belgeleri yanlış mı okuyorum? "" "Bir değişkenin oturum değişkeni olduğunu açıkça belirtmek için adından önce SESSION, @@ session. Veya @@." "
İle işaretlenir

5
@RobM, Yanlış okuyorsun. Yalnızca madde işaretindeki paragrafı değil, paragrafın tamamını okuyun. Basitçe söylemek gerekirse, iki tür oturum değişkeni vardır: 1) Kullanıcı tanımlı oturum değişkenleri ve 2) sistem  tanımlı oturum değişkenleri. Düğmesini kullanarak kullanıcı tanımlı oturum değişkeni ayarlayamazsınız @@. Örneğin, set@@my_var=1, set@@session.my_var=1, ve set session my_var=1çünkü işe yaramaz my_varbir değil sistem Yapabileceğimiz oysa değişken set@@big_tables=1, set@@session.big_tables=1ve set session big_tables=1çünkübig_tables bir sistem değişkendir.
Pacerier

1
@GovindRai: Quassnoi'nin cevabında, öneki var2olmayan bir değişkendir @, ancak bir sistem değişkeni değildir: bir işlem değişkeni. Saklı yordamda (saklı program olarak da bilinir) buna izin verilir. Saklı yordamlar dışında bir değişken @, bir sistem değişkenidir.
LarsH

10

MSSQL, yordamlar içindeki değişkenlerin DECLAREd olmasını ve milletlerin @Variable sözdizimini kullanmasını gerektirir (DECLARE @TEXT VARCHAR (25) = 'text'). Ayrıca MS, üstteki tüm DECLARE'ları gerektiren mySQL'in aksine, yordamdaki herhangi bir blok içinde bildirimlere izin verir.

Komut satırında iyi olsa da, mySQL saklı yordamlar içinde "set = @variable" kullanarak riskli hissediyorum. Kapsam sınırları boyunca hiçbir kapsam ve değişken yaşamaz. Bu, JavaScript'te "var" öneki olmadan bildirilen değişkenlere benzer; bunlar daha sonra genel ad alanıdır ve beklenmedik çarpışmalar ve üzerine yazmalar oluşturur.

MySQL iyi millet bir saklı yordam içinde çeşitli blok düzeylerinde DECLARE @Variable izin verir umuyoruz. @ İşaretine dikkat edin. @ Sign öneki, değişken adlarını tablo sütun adlarından ayırmaya yardımcı olur - genellikle aynıdır. Tabii ki, her zaman bir "v" veya "l_" öneki eklenebilir, ancak @ işareti, değişken adının verileri tıkamadan ayıklayabileceğiniz sütunla eşleşmesinin kullanışlı ve kısa bir yoludur.

MySQL, saklı yordamlar için yenidir ve ilk sürümleri için iyi bir iş çıkarmışlardır. Burada nereden aldıklarını görmek ve dilin sunucu tarafı özelliklerini olgunlaştırmak bir zevk olacaktır.


3

Prensip olarak, Saklı Yordamlar içinde UserDefinedVariables (@ ile ekli) kullanıyorum. Bu, özellikle iki veya daha fazla Saklı Yordamda bu değişkenlere ihtiyaç duyduğumda hayatı kolaylaştırır. Sadece TEK Saklı Yordam içinde bir değişkene ihtiyaç duyduğumda, bir Sistem Değişkeni kullanıyorum (@ ekli olmadan).

@Xybo: StoredProcedures'ta @variables kullanmanın neden riskli olması gerektiğini anlamıyorum. "Kapsam" ve "sınırları" biraz daha kolay açıklayabilir misiniz (benim için yeni başlayanlar gibi)?


3
Bu, temel yazılım mühendisliği ilkelerini ihlal eder. Lütfen kapsamın tam olarak ne olduğunu ve global değişkenleri kullanmanın neden genellikle korkunç bir fikir olduğunu anlayana kadar başka bir kod satırı yazmayın. 101 programlama dersi aldığımda, hemen hemen her şey için bir global kullanmayı hatırladığım gibi, otomatik bir "F" ile sonuçlanacaktır. Özel istisnalar vardır, ancak genel bir kural olarak, sadece yapmayın!
BuvinJ

Neden? - @ Değişkenler her MySQL Kitabında kesinlikle yaygındır.
Peter

Elbette, işlev çağrıları, yordamları, tetikleyicileri vb. Olmayan bir "düz" komut dosyasında ve yalnızca bu basit komut dosyasını veya sınırlı bir komut kümesini yürütecek ve oturumu sonlandıracaksanız (böylece küresellerinizi yok edeceksiniz). Bu durumda, devam edin ve isterseniz kullanın. Ancak bunları bir işlev içinde KULLANMAYIN! Sadece Google küresel değişkenleri veya kapsamı olursanız, evrensel olarak kaşlarını çattığı fikri için anında geniş bir destek bulacaksınız. İşte bir başlangıç ​​noktası: wiki.c2.com/?GlobalVariablesAreBad veya daha genel bir açıklama için: en.wikipedia.org/wiki/Global_variable
BuvinJ

2
MySQL'de @ değişkenler globaldir. Bu kolayca onaylanır. Bir fonksiyonun dışını ayarlayın ve ardından bir fonksiyonun içinde değerlendirin. Tersine, bir fonksiyonun içine yerleştirin ve onu fonksiyonun dışında değerlendirin. Fonksiyonun bu kapsamı korumadığını göreceksiniz. Birbirlerinin ayak parmaklarına basarlar.
BuvinJ

1
MySQL terminolojisini kullanarak, @@GLOBALdeğişkenler daha "global" ve sinsidir. Oturumları geçiyorlar! @variables"oturum kapsamı" var, en azından onlar bu şekilde kapalı kalırlar. Ancak "global" kapsam dediğiniz herhangi bir normal dilde (işlevler arası vb. Olduğunda). MySQL "küresel" kavramı belki de "evrensel" olarak adlandırılmalıdır, çünkü onu çalıştıran sürecin sınırlarının ötesine uzanır. "Global" normalde bunu standart bir dilde yapamaz, çünkü süreçler bellek alanını paylaşmaz. Bu, SQL'in (uçucuya karşı) kalıcı eğiliminden kaynaklanır.
BuvinJ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.