مای اس کیو ال db/mysql
اتصال به MySQL و MariaDB.
واردسازی دیتابیس.مای اس کیو ال
- آموزش: یک کتابفروشی کوچک در یازده گام
- ۱. اتصال
- ۲. ساختن جدولها
- ۳. درج ردیف
- ۴. خواندن ردیفها درون ساختارهای خودتان
- ۵. مقدارهای کاربر، به شکل امن
- ۶. مقدار NULL
- ۷. بهروزرسانی و حذف
- ۸. تراکنش
- ۹. خطاها
- ۱۰. رابط مشترک و استخر اتصال
- ۱۱. گزارش فروش
- درونریزی انبوه و درج یا بهروزرسانی
- مهاجرت ساختار پایگاه داده
- رمزنگاری و حالتهای TLS
- کدام تابع برای کدام کار
- گونهها
- تابعها
این بسته پروتکل کارخواه MySQL و MariaDB را خودش پیاده میکند و به هیچ کتابخانهی بیرونی نیاز ندارد: نه libmysqlclient نصب میخواهد و نه پیوند دادن چیزی. ورود را با mysql_native_password یا caching_sha2_password انجام میدهد، هر جا سرور TLS داشته باشد اتصال را رمزنگاری میکند و همان هنگام دستدادن utf8mb4 را میخواهد، پس متن فارسی و ایموجی از نخستین پرسمان درست کار میکنند. تابعها همان شکل API زبان C را دارند (بازکردن، اجرا، پرسمان، بعدی، پایان) و اتصال هر اتصال را به اتصال مشترک بستهی دیتابیس تبدیل میکند، تا کدی که برای آن رابط نوشته شده روی SQLite و PostgreSQL هم اجرا شود. این صفحه با یک آموزش شروع میشود و مرجع همهی تابعها پس از آن میآید.
آموزش: یک کتابفروشی کوچک در یازده گام
گامهای زیر پایگاه دادهی یک کتابفروشی کوچک را میسازند: جدولی برای کتابها، جدولی برای سفارشها و کدی برای فروختن، پر کردن انبار و گزارش گرفتن. هر گام یک برنامهی کامل است و خروجی زیر آن همان چیزی است که در برابر یک سرور واقعی MariaDB ۱۱.۸ چاپ کرد. گامها را به ترتیب اجرا کنید، چون هر گام با ردیفهایی کار میکند که گامهای قبل گذاشتهاند.
اول یک سرور راه بیندازید. با داکر یک فرمان کافی است و همین فرمان پایگاه داده و کاربری را که برنامهها با آن وارد میشوند هم میسازد:
docker run -d --name shop-db -p 3306:3306 -e MARIADB_ROOT_PASSWORD=rootpw -e MARIADB_DATABASE=shop -e MARIADB_USER=salam -e MARIADB_PASSWORD=secret mariadb:11.8
برنامهها با کاربر salam و گذرواژهی secret به 127.0.0.1 روی درگاه ۳۳۰۶ وصل میشوند و پایگاه دادهی shop را به کار میبرند. خروجیها از MariaDB گرفته شدهاند. MySQL 8 همین پروتکل را دارد و بسته با آن هم کار میکند، ولی چند دستور اینجا نامهای MariaDB را به کار میبرند: در MySQL جدول وضعیت گام ۱ performance_schema.session_status است.
۱. اتصال
بازکردن میزبان، نام کاربر، گذرواژه، نام پایگاه داده و درگاه را میگیرد و همیشه یک پایگاه داده برمیگرداند. پیش از هر کاری آن را با معتبر بسنجید: اگر ورود شکست بخورد دستگیره خالی است و خطا دلیلش را میگوید. نام پایگاه دادهی "" بدون انتخاب پایگاه داده وصل میشود و انتخاب پایگاه داده بعدا آن را برمیگزیند. بستن به سرور خداحافظی میفرستد و اتصال را آزاد میکند، پس درست پس از بررسی آن را دیرکن کنید.
واردسازی دیتابیس.مای اس کیو ال
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
سرچاپ "سرور:"، مای اس کیو ال.نسخه سرور(پ)
سرچاپ "کارخواه:"، مای اس کیو ال.نسخه کلاینت()
سرچاپ "زنده است:"، مای اس کیو ال.پینگ(پ)
سرچاپ "پایگاه داده:"، مای اس کیو ال.پرسمان متن(پ، "SELECT DATABASE()")
سرچاپ "کدینگ:"، مای اس کیو ال.پرسمان متن(پ، "SELECT @@character_set_connection")
سرچاپ "رمزنگاری:"، مای اس کیو ال.پرسمان متن(پ، "SELECT VARIABLE_VALUE FROM information_schema.SESSION_STATUS WHERE VARIABLE_NAME = 'Ssl_version'")
رمز غلط := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "wrong"، "shop"، ۳۳۰۶)
سرچاپ "با گذرواژه نادرست:"، مای اس کیو ال.معتبر(رمز غلط)
سرچاپ مای اس کیو ال.خطا(رمز غلط)
بی پاسخ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۷)
سرچاپ مای اس کیو ال.خطا(بی پاسخ)
برگشت ۰
پایانخط رمزنگاری نشان میدهد که نشست رمزنگاری شده، با اینکه برنامه چیزی نخواسته بود: TLS در MariaDB ۱۱.۸ به طور پیشفرض روشن است و کارخواه هر جا باشد از آن استفاده میکند. بخش رمزنگاری و حالتهای TLS در پایین نشان میدهد چطور آن را اجباری یا خاموش کنید. دقت کنید که کدخطا فقط روی اتصالی کار میکند که برقرار شده؛ برای بازکردن ناموفق فقط پیام هست.
۲. ساختن جدولها
اجرا یک دستور را اجرا میکند و اگر کار کرد ۰ و اگر نه ۱- برمیگرداند. دستور SQL چندخطی را راحتتر است در رشتهی بکتیک بنویسید که خطها و نقلقولها را همانطور که نوشتهاید نگه میدارد. هر اجرا یک دستور را اجرا میکند؛ برای چند دستور، برای هر کدام یک بار صدایش بزنید.
واردسازی دیتابیس.مای اس کیو ال
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
مای اس کیو ال.اجرا(پ، "DROP TABLE IF EXISTS orders")
مای اس کیو ال.اجرا(پ، "DROP TABLE IF EXISTS books")
کتاب ها := `CREATE TABLE books (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL UNIQUE,
author VARCHAR(100) NOT NULL,
price DECIMAL(8, 2) NOT NULL,
stock INT NOT NULL DEFAULT 0,
isbn VARCHAR(20) NULL,
details JSON NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4`
سرچاپ "جدول کتابها:"، مای اس کیو ال.اجرا(پ، کتاب ها)
سفارش ها := `CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
book_id INT NOT NULL,
customer VARCHAR(100) NOT NULL,
qty INT NOT NULL,
total DECIMAL(10, 2) NOT NULL,
FOREIGN KEY (book_id) REFERENCES books (id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4`
سرچاپ "جدول سفارشها:"، مای اس کیو ال.اجرا(پ، سفارش ها)
ناپایا ن := مای اس کیو ال.پرسمان(پ، "SELECT TABLE_NAME, COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'shop' AND TABLE_NAME IN ('books', 'orders') GROUP BY TABLE_NAME ORDER BY TABLE_NAME")
تا مای اس کیو ال.بعدی(ن):
سرچاپ "جدول"، مای اس کیو ال.متن(ن، ۰)، "ستون دارد:"، مای اس کیو ال.عدد صحیح(ن، ۱)
پایان
مای اس کیو ال.پایان(ن)
برگشت ۰
پایانجدول books یک ستون isbn دارد که میتواند خالی (NULL) باشد و یک ستون JSON برای جزئیاتی که از کتابی به کتاب دیگر فرق میکند. InnoDB موتوری است که تراکنش و کلید خارجی دارد و utf8mb4 همان UTF-8 واقعی چهاربایتی است؛ utf8 قدیمی MySQL نمیتواند همهی نویسهها را نگه دارد.
۳. درج ردیف
پس از یک INSERT، شناسه آخرین درج شناسهی AUTO_INCREMENT را که سرور برگزیده میدهد و ردیف های تحت تاثیر (یا نام دیگرش تعداد تغییرات) میگوید چند ردیف درج شد. یک INSERT با چند فهرست مقدار بسیار سریعتر از چند درج تکی است و در آن شناسه آخرین درج شناسهی نخستین ردیف تازه است.
واردسازی دیتابیس.مای اس کیو ال
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
مای اس کیو ال.اجرا(پ، `INSERT INTO books (title, author, price, stock, details) VALUES ('Master and Commander', 'Patrick O''Brian', 14.50, 4, '{"pages": 412, "tags": ["sea", "navy"]}')`)
سرچاپ "شناسه کتاب اول:"، مای اس کیو ال.شناسه آخرین درج(پ)
مای اس کیو ال.اجرا(پ، "INSERT INTO books (title, author, price, stock, isbn) VALUES ('The Remains of the Day', 'Kazuo Ishiguro', 11.25, 2, '9780571200733')")
سرچاپ "شناسه کتاب دوم:"، مای اس کیو ال.شناسه آخرین درج(پ)
چند ردیف := `INSERT INTO books (title, author, price, stock, details) VALUES
('A Wizard of Earthsea', 'Ursula K. Le Guin', 9.99, 6, '{"pages": 183, "tags": ["fantasy"]}'),
('The Blind Owl', 'Sadegh Hedayat', 8.00, 3, NULL),
('شازده احتجاب', 'هوشنگ گلشیری', 7.50, 5, '{"pages": 120, "tags": ["novel"]}')`
مای اس کیو ال.اجرا(پ، چند ردیف)
سرچاپ "ردیفهای افزوده:"، مای اس کیو ال.ردیف های تحت تاثیر(پ)
سرچاپ "شناسه نخستین ردیف همین درج:"، مای اس کیو ال.شناسه آخرین درج(پ)
سرچاپ "شمار کتابها:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT COUNT(*) FROM books")
سرچاپ "کل موجودی:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT SUM(stock) FROM books")
برگشت ۰
پایاندرون SQL نقلقول تکی دو بار نوشته میشود (O''Brian). برای متنی که خودتان نوشتهاید این کافی است؛ متنی که از کاربر میآید باید از نقل قول یا اسکیپ بگذرد، همانطور که گام ۵ نشان میدهد.
۴. خواندن ردیفها درون ساختارهای خودتان
پرسمان یک نتیجه برمیگرداند که همهی ردیفهایش از پیش از سرور خوانده شدهاند. آن را در متغیر ناپایا نگه دارید، چون بعدی آن را به ردیف بعد میبرد و وقتی ردیفی نماند نادرست برمیگرداند. متن، عدد صحیح، عدد صحیح۶۴ و عدد اعشار یک ستون از ردیف کنونی را با شمارهاش (از ۰) میخوانند و پایان نتیجه را آزاد میکند. اگر این حلقه را در تابعی بگذارید که وکتوری از ساختار خودتان برمیگرداند، SQL در یک جا میماند.
واردسازی رشته
واردسازی دیتابیس.مای اس کیو ال
ساختار کتاب:
همگانی شناسه: صحیح = ۰
همگانی عنوان: رشته = ""
همگانی نویسنده: رشته = ""
همگانی قیمت: رشته = ""
همگانی موجودی: صحیح = ۰
پایان
تابع خواندن کتاب ها(پ: مای اس کیو ال.پایگاه داده، دستور: رشته): وکتور<کتاب>:
ناپایا خروجی := وکتور {} برگردان وکتور<کتاب>
ناپایا ن := مای اس کیو ال.پرسمان(پ، دستور)
اگر وارونه مای اس کیو ال.پرسمان معتبر(ن):
سرچاپ "پرسمان شکست خورد:"، مای اس کیو ال.خطا(پ)
برگشت خروجی
پایان
تا مای اس کیو ال.بعدی(ن):
خروجی.بیفزا(کتاب {
شناسه = مای اس کیو ال.عدد صحیح(ن، ۰)، عنوان = مای اس کیو ال.متن(ن، ۱)، نویسنده = مای اس کیو ال.متن(ن، ۲)، قیمت = مای اس کیو ال.متن(ن، ۳)، موجودی = مای اس کیو ال.عدد صحیح(ن، ۴)
})
پایان
مای اس کیو ال.پایان(ن)
برگشت خروجی
پایان
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
ن := مای اس کیو ال.پرسمان(پ، "SELECT id, title, author, price, stock FROM books LIMIT 0")
ناپایا نام ها := وکتور {} برگردان وکتور<رشته>
تکرار مای اس کیو ال.تعداد ستون(ن) در ستون:
نام ها.بیفزا(مای اس کیو ال.نام ستون(ن، ستون))
پایان
مای اس کیو ال.پایان(ن)
سرچاپ "ستونها:"، رشته.بپیوند(نام ها، ", ")
کتاب ها := خواندن کتاب ها(پ، "SELECT id, title, author, price, stock FROM books ORDER BY price DESC")
هر ک در کتاب ها:
سرچاپ ک.شناسه، ک.عنوان، "از"، ک.نویسنده، "به قیمت"، ک.قیمت، "و موجودی"، ک.موجودی
پایان
ارزان ها := خواندن کتاب ها(پ، "SELECT id, title, author, price, stock FROM books WHERE price < 9 ORDER BY id")
سرچاپ "زیر ۹:"، ارزان ها.طول()
برگشت ۰
پایانسرور هر مقدار را به شکل متن میفرستد و تابعهای ستون آن را تبدیل میکنند، پس DECIMALی که با متن خوانده شود دقیق میماند (14.50) ولی عدد اعشار آن را به کسر دودویی تبدیل میکند. پول را به شکل متن یا عدد صحیح در کوچکترین واحد (مثلا سنت) نگه دارید و جمع زدن را به SQL بسپارید. تعداد ستون و نام ستون ستونها را توصیف میکنند که برای چاپ سرستون یا ساختن فایل CSV به کار میآید؛ LIMIT 0 ستونها را بی هیچ ردیفی میدهد.
۵. مقدارهای کاربر، به شکل امن
این بسته دستور آماده (prepared statement) ندارد، پس مقدار درون متن SQL قرار میگیرد. هرگز متن کاربر را مستقیم نچسبانید. نقل قول (یک متد پایگاه داده) متن را اسکیپ میکند و نقلقولها را دورش میگذارد؛ اسکیپ فقط اسکیپ میکند، برای وقتی که نقلقولها را خودتان مینویسید. هر دو نقلقول، بکاسلش، خط تازه و بایت NUL را همانطور که سرور میخواند اسکیپ میکنند.
واردسازی رشته
واردسازی دیتابیس.مای اس کیو ال
تابع شمار کتاب های نویسنده(پ: مای اس کیو ال.پایگاه داده، نام: رشته): صحیح:
برگشت مای اس کیو ال.پرسمان عدد(پ، "SELECT COUNT(*) FROM books WHERE author = " + پ.نقل قول(نام))
پایان
تابع الگوی جستجو(پ: مای اس کیو ال.پایگاه داده، واژه: رشته): رشته:
ناپایا امن := مای اس کیو ال.اسکیپ(پ، واژه)
امن = رشته.جایگزینی(امن، "%"، "\\%")
امن = رشته.جایگزینی(امن، "_"، "\\_")
برگشت "'%" + امن + "%'"
پایان
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
سرچاپ "از Patrick O'Brian:"، شمار کتاب های نویسنده(پ، "Patrick O'Brian")
سرچاپ "از هوشنگ گلشیری:"، شمار کتاب های نویسنده(پ، "هوشنگ گلشیری")
حمله := "nobody' OR '1'='1"
سرچاپ "نقلقولشده:"، پ.نقل قول(حمله)
سرچاپ "پرسمان امن پیدا میکند:"، شمار کتاب های نویسنده(پ، حمله)
ناامن := "SELECT COUNT(*) FROM books WHERE author = '" + حمله + "'"
سرچاپ "پرسمان چسبانده پیدا میکند:"، مای اس کیو ال.پرسمان عدد(پ، ناامن)
سرچاپ "عنوانهای دارای the:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT COUNT(*) FROM books WHERE title LIKE " + الگوی جستجو(پ، "the"))
سرچاپ "عنوانهای دارای %:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT COUNT(*) FROM books WHERE title LIKE " + الگوی جستجو(پ، "%"))
برگشت ۰
پایانپرسمان چسبانده همهی کتابها را میشمارد، چون نقلقول مهاجم رشته را بست و OR '1'='1' بخشی از شرط شد. پرسمان نقلقولشده دنبال نویسندهای میگردد که نامش دقیقا همین متن است و چیزی پیدا نمیکند. LIKE یک قدم بیشتر میخواهد: % و _ آنجا نویسهی عاماند و اسکیپ به آنها دست نمیزند، پس الگوی جستجو پیش از هر کدام یک بکاسلش میگذارد. عددها به شکل عدد واقعی از همه امنترند: ورودی را اول به صحیح تبدیل کنید و با رشته.از عدد دوباره بنویسید.
۶. مقدار NULL
خالی است NULL را از رشتهی خالی جدا میکند. تابعهای دیگر ستون برای NULL یک مقدار خنثی میدهند (""، ۰ یا ۰.۰) که راحت است ولی یعنی بدون پرسیدن نمیتوانید بیمقدار را از صفر تشخیص بدهید. فیلدهای JSON با JSON_VALUE به شکل متن معمولی برمیگردند و اگر سند یا کلید نباشد NULL.
واردسازی دیتابیس.مای اس کیو ال
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
مای اس کیو ال.اجرا(پ، "UPDATE books SET isbn = '9780393307054' WHERE id = 1")
ناپایا ن := مای اس کیو ال.پرسمان(پ، "SELECT title, isbn, JSON_VALUE(details, '$.pages') FROM books ORDER BY id")
تا مای اس کیو ال.بعدی(ن):
ناپایا شابک := مای اس کیو ال.متن(ن، ۱)
اگر مای اس کیو ال.خالی است(ن، ۱):
شابک = "(بی شابک)"
پایان
ناپایا صفحه ها := "نامعلوم"
اگر وارونه مای اس کیو ال.خالی است(ن، ۲):
صفحه ها = مای اس کیو ال.متن(ن، ۲) + " صفحه"
پایان
سرچاپ مای اس کیو ال.متن(ن، ۰)، "|"، شابک، "|"، صفحه ها
پایان
مای اس کیو ال.پایان(ن)
سرچاپ "با IS NULL:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT COUNT(*) FROM books WHERE isbn IS NULL")
سرچاپ "با = NULL:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT COUNT(*) FROM books WHERE isbn = NULL")
سرچاپ "عدد صحیحِ NULL:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT NULL")
سرچاپ "COALESCE:"، مای اس کیو ال.پرسمان متن(پ، "SELECT COALESCE(isbn, 'none') FROM books WHERE id = 3")
برگشت ۰
پایاندر SQL هیچ چیز با NULL برابر نیست، حتی خود NULL، پس isbn = NULL هیچ ردیفی پیدا نمیکند؛ IS NULL بنویسید. COALESCE درون پرسمان به جای NULL یک مقدار پیشفرض میگذارد و یک بررسی را از برنامه کم میکند.
۷. بهروزرسانی و حذف
UPDATE و DELETE هم با اجرا اجرا میشوند و ردیف های تحت تاثیر میگوید چند ردیف را تغییر دادند. حساب را در خود SQL بنویسید (stock = stock + 10) تا دو برنامه که همزمان انبار را پر میکنند کار یکدیگر را پاک نکنند.
واردسازی دیتابیس.مای اس کیو ال
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
مای اس کیو ال.اجرا(پ، "UPDATE books SET stock = stock + 10 WHERE author = 'Kazuo Ishiguro'")
سرچاپ "موجودی افزوده شد:"، مای اس کیو ال.ردیف های تحت تاثیر(پ)
مای اس کیو ال.اجرا(پ، "UPDATE books SET price = price * 1.10 WHERE price < 9")
سرچاپ "قیمت تازه:"، مای اس کیو ال.ردیف های تحت تاثیر(پ)
مای اس کیو ال.اجرا(پ، "UPDATE books SET stock = 12 WHERE id = 2")
سرچاپ "گذاشتن همان مقدار دوباره تغییر میدهد:"، مای اس کیو ال.ردیف های تحت تاثیر(پ)
مای اس کیو ال.اجرا(پ، "DELETE FROM books WHERE title = 'The Blind Owl'")
سرچاپ "پاک شد:"، مای اس کیو ال.ردیف های تحت تاثیر(پ)
ناپایا ن := مای اس کیو ال.پرسمان(پ، "SELECT id, title, price, stock FROM books ORDER BY id")
تا مای اس کیو ال.بعدی(ن):
سرچاپ مای اس کیو ال.عدد صحیح(ن، ۰)، مای اس کیو ال.متن(ن، ۱)، مای اس کیو ال.متن(ن، ۲)، مای اس کیو ال.عدد صحیح(ن، ۳)
پایان
مای اس کیو ال.پایان(ن)
برگشت ۰
پایانMySQL و MariaDB ردیفهایی را میشمارند که واقعا تغییر کردند، نه ردیفهایی که با WHERE جور بودند: گذاشتن مقداری که stock از قبل دارد ۰ گزارش میشود. پیش از اینکه ۰ را پیدا نشد بدانید این را در نظر بگیرید و هر جا فرقش مهم است با یک SELECT بررسی کنید.
۸. تراکنش
هر سفارش دو نوشتن دارد: کم کردن موجودی و افزودن ردیف سفارش. یا هر دو انجام میشوند یا هیچ کدام. شروع تراکنش تراکنش را آغاز میکند، ثبت تراکنش نوشتههایش را نگه میدارد و بازگردانی آنها را دور میریزد. UPDATE فقط وقتی موجودی را کم میکند که به اندازهی کافی باشد و ردیف های تحت تاثیر به برنامه میگوید کم کرد یا نه.
واردسازی رشته
واردسازی دیتابیس.مای اس کیو ال
تابع ثبت سفارش(پ: مای اس کیو ال.پایگاه داده، کتاب: صحیح، مشتری: رشته، شمار: صحیح): منطقی:
اگر مای اس کیو ال.شروع تراکنش(پ) != ۰:
برگشت نادرست
پایان
شناسه := رشته.از عدد(کتاب)
تعداد := رشته.از عدد(شمار)
مای اس کیو ال.اجرا(پ، "UPDATE books SET stock = stock - " + تعداد + " WHERE id = " + شناسه + " AND stock >= " + تعداد)
اگر مای اس کیو ال.ردیف های تحت تاثیر(پ) != ۱:
مای اس کیو ال.بازگردانی(پ)
برگشت نادرست
پایان
دستور := "INSERT INTO orders (book_id, customer, qty, total) SELECT id, " + پ.نقل قول(مشتری) + ", " + تعداد + ", price * " + تعداد + " FROM books WHERE id = " + شناسه
اگر مای اس کیو ال.اجرا(پ، دستور) != ۰:
مای اس کیو ال.بازگردانی(پ)
برگشت نادرست
پایان
برگشت مای اس کیو ال.ثبت تراکنش(پ) == ۰
پایان
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
سرچاپ "سارا، ۲ نسخه از کتاب ۳:"، ثبت سفارش(پ، ۳، "سارا"، ۲)
سرچاپ "رضا، ۱ نسخه از کتاب ۱:"، ثبت سفارش(پ، ۱، "رضا"، ۱)
سرچاپ "ندا، ۳ نسخه از کتاب ۵:"، ثبت سفارش(پ، ۵، "ندا"، ۳)
سرچاپ "علی، ۹ نسخه از کتاب ۱:"، ثبت سفارش(پ، ۱، "علی"، ۹)
سرچاپ "امید، ۱ نسخه از کتاب ۹۹:"، ثبت سفارش(پ، ۹۹، "امید"، ۱)
سرچاپ "سفارشها:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT COUNT(*) FROM orders")
سرچاپ "موجودی کتاب ۱:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT stock FROM books WHERE id = 1")
سرچاپ "موجودی کتاب ۳:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT stock FROM books WHERE id = 3")
سرچاپ "فروش:"، مای اس کیو ال.پرسمان متن(پ، "SELECT SUM(total) FROM orders")
برگشت ۰
پایانعلی بیش از موجودی فروشگاه خواست و سفارش کتاب ۹۹ کتابی پیدا نکرد، پس هر دو بازگردانده شدند و ردی به جا نگذاشتند. درون تراکنش، InnoDB ردیفهایی را که تغییر میدهد تا ثبت تراکنش قفل میکند، پس دو سفارش برای آخرین نسخه نمیتوانند هر دو موفق شوند. راه دیگر ثبت خودکار(پ، نادرست) است: از آن پس هر دستور منتظر یک ثبت تراکنش صریح میماند. در MySQL هر CREATE، ALTER یا DROP خودش ثبت میشود، پس تغییر ساختار جدول را وسط تراکنشی که شاید بازگردانده شود نگذارید.
۹. خطاها
وقتی اجرا ۱- برمیگرداند یا پرسمان معتبر نادرست است، کدخطا شمارهی خطای سرور و خطا پیامش را میدهد. برنامه باید روی شماره تصمیم بگیرد: ۱۰۶۲ کلید تکراری است، ۱۴۵۲ ردیف والد ناموجود، ۱۳۶۴ ستون اجباری بیمقدار، ۱۰۶۴ خطای نحوی و ۱۱۴۶ جدول ناموجود.
واردسازی دیتابیس.مای اس کیو ال
تابع امتحان(پ: مای اس کیو ال.پایگاه داده، دستور: رشته):
اگر مای اس کیو ال.اجرا(پ، دستور) == ۰:
سرچاپ "انجام شد"
برگشت
پایان
سرچاپ "کد خطا"، مای اس کیو ال.کدخطا(پ)، "پیام:"، مای اس کیو ال.خطا(پ)
پایان
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
امتحان(پ، "INSERT INTO books (title, author, price) VALUES ('A Wizard of Earthsea', 'Someone', 5)")
امتحان(پ، "INSERT INTO orders (book_id, customer, qty, total) VALUES (99, 'Omid', 1, 5)")
امتحان(پ، "INSERT INTO books (title, author) VALUES ('No Price', 'Nobody')")
امتحان(پ، "SELEC title FROM books")
امتحان(پ، "UPDATE books SET stock = stock WHERE id = 1")
ن := مای اس کیو ال.پرسمان(پ، "SELECT name FROM authors")
اگر وارونه مای اس کیو ال.پرسمان معتبر(ن):
سرچاپ "پرسمان شکست خورد:"، مای اس کیو ال.کدخطا(پ)، مای اس کیو ال.خطا(پ)
پایان
سرچاپ "هنوز وصل است:"، مای اس کیو ال.پینگ(پ)
سرچاپ "موجودی کتاب ۱:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT stock FROM books WHERE id = 1")
برگشت ۰
پایانخطا در یک دستور اتصال را خراب نمیکند؛ دستور بعدی عادی اجرا میشود، همانطور که دو خط آخر نشان میدهند. اتصال از دست رفته فرق دارد: پینگ نادرست برمیگرداند و تنها چاره یک بازکردن تازه است. خطای ۱۰۶۲ راه تمیزی هم برای فهمیدن وجود یک ردیف است: درجش کنید و تکراری بودن را مدیریت کنید، به جای اینکه اول بپرسید و با برنامهای دیگر مسابقه بدهید.
۱۰. رابط مشترک و استخر اتصال
اتصال یک اتصال را به شکل پویا دیتابیس.اتصال میپیچد. از این راه کمکتابعهای دیتابیس روی MySQL کار میکنند: پرسمان عدد، اجرا کن، در تراکنش و بقیه. استخر چند اتصال باز را نگه میدارد و با گرفتن و رهاکردن آنها را با شماره قرض میدهد، تا سرور برای هر درخواست دوباره وارد نشود.
واردسازی دیتابیس
واردسازی دیتابیس.مای اس کیو ال
تابع ریشه:
ناپایا استخر := دیتابیس.استخر جدید(۳)
تکرار ۳ در شماره:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال"، شماره، "برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیتابیس.افزودن(استخر، مای اس کیو ال.اتصال(پ))
پایان
سرچاپ "اندازه:"، دیتابیس.اندازه(استخر)، "بیکار:"، دیتابیس.بیکار(استخر)
الف := دیتابیس.گرفتن(استخر)
ب := دیتابیس.گرفتن(استخر)
اتصال الف := دیتابیس.اتصال اجارهای(استخر، الف)
اتصال ب := دیتابیس.اتصال اجارهای(استخر، ب)
سرچاپ "نوع:"، اتصال الف.نوع()، "در کار:"، دیتابیس.در استفاده(استخر)
سرچاپ "نشستهای جدا:"، دیتابیس.پرسمان عدد(اتصال الف، "SELECT CONNECTION_ID()") != دیتابیس.پرسمان عدد(اتصال ب، "SELECT CONNECTION_ID()")
انبار := وکتور {} برگردان وکتور<رشته>
انبار.بیفزا("UPDATE books SET stock = stock + 5 WHERE id = 1")
انبار.بیفزا("UPDATE books SET stock = stock + 5 WHERE id = 3")
سرچاپ "افزایش موجودی در یک تراکنش:"، دیتابیس.در تراکنش(اتصال ب، انبار)
سرچاپ "موجودی کتاب ۱ از دید اتصال دیگر:"، دیتابیس.پرسمان عدد(اتصال الف، "SELECT stock FROM books WHERE id = 1")
ج := دیتابیس.گرفتن(استخر)
چهارمی := دیتابیس.گرفتن(استخر)
سرچاپ "اجاره چهارم:"، دیتابیس.اجاره شده(چهارمی)
دیتابیس.رهاکردن(استخر، الف)
دیتابیس.رهاکردن(استخر، ب)
دیتابیس.رهاکردن(استخر، ج)
سرچاپ "دوباره بیکار:"، دیتابیس.بیکار(استخر)
سرچاپ "اتصالهای مرده حذفشده:"، دیتابیس.حذف مرده ها(استخر)
دیتابیس.آزادکردن(استخر)
برگشت ۰
پایانهر اتصال نشست خودش را دارد، با CONNECTION_ID()، تراکنش و شناسهی آخرین درج خودش. یک اتصال را همزمان از دو نخ به کار نبرید: به هر نخ اتصال خودش را بدهید یا یکی از استخر قرض بگیرید. وقتی گرفتن مقدار بدون اجاره برمیگرداند همهی اتصالها مشغولاند؛ صبر کنید و دوباره بخواهید، یا اتصال دیگری باز کنید. حذف مرده ها اتصالهای بیکار را پینگ میکند و آنهایی را که سرور بسته است کنار میگذارد.
۱۱. گزارش فروش
فایدهی نگه داشتن سفارشها در SQL این است که هر پرسش یک پرسمان میشود. JOIN و GROUP BY فروش هر کتاب را جمع میزنند، GROUP_CONCAT یک فهرست را در یک مقدار متنی جمع میکند و تابعهای JSON درون ستون details میگردند. تعداد ردیف پیش از حلقه میگوید نتیجه چند ردیف دارد.
واردسازی دیتابیس.مای اس کیو ال
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
فروش := `SELECT b.title, SUM(o.qty), SUM(o.total), COUNT(DISTINCT o.customer)
FROM orders o JOIN books b ON b.id = o.book_id
GROUP BY b.id, b.title
ORDER BY SUM(o.total) DESC`
ناپایا ن := مای اس کیو ال.پرسمان(پ، فروش)
سرچاپ مای اس کیو ال.تعداد ردیف(ن)، "کتاب فروش رفته"
تا مای اس کیو ال.بعدی(ن):
سرچاپ مای اس کیو ال.متن(ن، ۰)، "| نسخه"، مای اس کیو ال.عدد صحیح(ن، ۱)، "| فروش"، مای اس کیو ال.متن(ن، ۲)، "| مشتری"، مای اس کیو ال.عدد صحیح(ن، ۳)
پایان
مای اس کیو ال.پایان(ن)
سرچاپ "هرگز فروش نرفته:"، مای اس کیو ال.پرسمان متن(پ، "SELECT GROUP_CONCAT(title ORDER BY id SEPARATOR ', ') FROM books WHERE id NOT IN (SELECT book_id FROM orders)")
سرچاپ "درباره دریا:"، مای اس کیو ال.پرسمان متن(پ، "SELECT title FROM books WHERE JSON_CONTAINS(details, '\"sea\"', '$.tags')")
سرچاپ "صفحههای روی قفسه:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT SUM(stock * JSON_VALUE(details, '$.pages')) FROM books")
سرچاپ "ارزش موجودی:"، مای اس کیو ال.پرسمان متن(پ، "SELECT SUM(stock * price) FROM books")
برگشت ۰
پایانکتابفروشی آماده است: ساختار جدولها، نوشتنهایی که نیمهکاره نمیمانند، خواندن درون ساختارها و گزارش. بخشهای زیر کارهایی را پوشش میدهند که در این داستان جا نگرفتند.
درونریزی انبوه و درج یا بهروزرسانی
محمولهای از کتابها، که بعضی تازهاند و بعضی از قبل روی قفسه، یک دستور است: یک INSERT چندردیفی با ON DUPLICATE KEY UPDATE. ردیفی که عنوان UNIQUE آن از قبل هست، به جای شکست با خطای ۱۰۶۲، همان ردیف را بهروز میکند. هر مقدار باز هم از نقل قول میگذرد و رشته.بپیوند ردیفها را کنار هم میگذارد.
واردسازی رشته
واردسازی دیتابیس.مای اس کیو ال
ساختار رسیده:
همگانی عنوان: رشته = ""
همگانی نویسنده: رشته = ""
همگانی قیمت: رشته = ""
همگانی نسخه ها: صحیح = ۰
پایان
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
ناپایا جعبه := وکتور {} برگردان وکتور<رسیده>
جعبه.بیفزا(رسیده { عنوان = "A Wizard of Earthsea"، نویسنده = "Ursula K. Le Guin"، قیمت = "9.99"، نسخه ها = ۴ })
جعبه.بیفزا(رسیده { عنوان = "The Tombs of Atuan"، نویسنده = "Ursula K. Le Guin"، قیمت = "9.99"، نسخه ها = ۳ })
جعبه.بیفزا(رسیده { عنوان = "Kafka on the Shore"، نویسنده = "Haruki Murakami"، قیمت = "13.40"، نسخه ها = ۲ })
ناپایا ردیف ها := وکتور {} برگردان وکتور<رشته>
هر ک در جعبه:
ردیف ها.بیفزا("(" + پ.نقل قول(ک.عنوان) + ", " + پ.نقل قول(ک.نویسنده) + ", " + ک.قیمت + ", " + رشته.از عدد(ک.نسخه ها) + ")")
پایان
دستور := "INSERT INTO books (title, author, price, stock) VALUES " + رشته.بپیوند(ردیف ها، ", ") + " ON DUPLICATE KEY UPDATE stock = stock + VALUES(stock), price = VALUES(price)"
اگر مای اس کیو ال.اجرا(پ، دستور) != ۰:
سرچاپ "درونریزی شکست خورد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
سرچاپ "ردیفهای تحت تاثیر:"، مای اس کیو ال.ردیف های تحت تاثیر(پ)
سرچاپ "شمار کتابها:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT COUNT(*) FROM books")
سرچاپ "موجودی Earthsea:"، مای اس کیو ال.پرسمان عدد(پ، "SELECT stock FROM books WHERE title = 'A Wizard of Earthsea'")
برگشت ۰
پایاندر این نوع درج، ردیف های تحت تاثیر برای هر ردیف تازه ۱ و برای هر ردیف بهروزشده ۲ میشمارد، پس ۴ اینجا یعنی دو کتاب تازه و یک پر کردن انبار. سرور اندازهی هر دستور را محدود میکند (max_allowed_packet که در MariaDB به طور پیشفرض ۱۶ مگابایت است)، پس درونریزی بزرگ را به تکههای چند هزار ردیفی بشکنید و اگر باید همه با هم وارد شوند یا هیچ کدام، تکهها را در یک تراکنش بگذارید.
مهاجرت ساختار پایگاه داده
ساختار جدولهای یک برنامهی واقعی با زمان تغییر میکند. مهاجرت گر از بستهی دیتابیس گامهای شمارهدار را نگه میدارد که هر کدام یک متن SQL برای بالا رفتن و یکی برای برگشتن دارند، و گامهای اجراشده را در جدول schema_migrations ثبت میکند. مهاجرت به بالا را هنگام شروع برنامه صدا بزنید تا فقط گامهای تازه اجرا شوند.
واردسازی دیتابیس
واردسازی دیتابیس.مای اس کیو ال
تابع ریشه:
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
ا := مای اس کیو ال.اتصال(پ)
ناپایا م := دیتابیس.مهاجرت گر جدید()
دیتابیس.افزودن مهاجرت(م، ۱، "reviews"، "CREATE TABLE reviews (id INT AUTO_INCREMENT PRIMARY KEY, book_id INT NOT NULL, stars TINYINT NOT NULL)"، "DROP TABLE reviews")
دیتابیس.افزودن مهاجرت(م، ۲، "review text"، "ALTER TABLE reviews ADD COLUMN body TEXT NULL"، "ALTER TABLE reviews DROP COLUMN body")
سرچاپ "نسخه پیش از کار:"، دیتابیس.نسخه طرحواره(م، ا)، "در انتظار:"، دیتابیس.تعداد در انتظار(م، ا)
سرچاپ "اجرا شد:"، دیتابیس.مهاجرت به بالا(م، ا)
سرچاپ "نسخه پس از کار:"، دیتابیس.نسخه طرحواره(م، ا)
سرچاپ "اجرا شده در بار دوم:"، دیتابیس.مهاجرت به بالا(م، ا)
سرچاپ "ستونهای reviews:"، دیتابیس.پرسمان عدد(ا، "SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'shop' AND TABLE_NAME = 'reviews'")
سرچاپ "برگردانده شد:"، دیتابیس.بازگردانی(م، ا)
سرچاپ "نسخه اکنون:"، دیتابیس.نسخه طرحواره(م، ا)
سرچاپ "رفتن به نسخه ۰:"، دیتابیس.مهاجرت به(م، ا، ۰)
سرچاپ "جدول reviews مانده:"، دیتابیس.پرسمان عدد(ا، "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'shop' AND TABLE_NAME = 'reviews'")
دیتابیس.آزادکردن مهاجرت گر(م)
ا.بستن()
برگشت ۰
پایانمهاجرتگر هر گام را در یک تراکنش اجرا میکند، ولی MySQL هر CREATE و ALTER را خودش ثبت میکند، پس گامی که در میانه شکست بخورد ممکن است بخشی از کارش را به جا بگذارد. هر گام را به یک تغییر ساختار محدود کنید یا گامهایی بنویسید که اجرای دوبارهشان بیخطر است، مثل CREATE TABLE IF NOT EXISTS.
رمزنگاری و حالتهای TLS
کارخواه هر جا سرور TLS پیشنهاد کند رمزنگاری میکند و برنامه لازم نیست چیزی تنظیم کند. دو متغیر محیطی این رفتار را عوض میکنند. SALAM_MYSQL_SSL_MODE میتواند DISABLED (هرگز رمزنگاری نکن)، REQUIRED (سرور بدون TLS را نپذیر) یا VERIFY_IDENTITY (گواهی و نام میزبان را هم بررسی کن) باشد؛ اگر تنظیم نشود هر جا بتواند رمزنگاری میکند ولی گواهی را بررسی نمیکند. SALAM_MYSQL_SSL_CA فایل CA را برای بررسی نام میبرد.
واردسازی محیط
واردسازی دیتابیس.مای اس کیو ال
تابع وضعیت(پ: مای اس کیو ال.پایگاه داده، نام: رشته): رشته:
برگشت مای اس کیو ال.پرسمان متن(پ، "SELECT VARIABLE_VALUE FROM information_schema.SESSION_STATUS WHERE VARIABLE_NAME = '" + نام + "'")
پایان
تابع ریشه:
حالت := محیط.دریافت با پیش فرض("SALAM_MYSQL_SSL_MODE"، "(تنظیم نشده)")
سرچاپ "SALAM_MYSQL_SSL_MODE:"، حالت
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "salam"، "secret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ "اتصال برقرار نشد:"، مای اس کیو ال.خطا(پ)
برگشت ۱
پایان
دیرکن مای اس کیو ال.بستن(پ)
نسخه := وضعیت(پ، "Ssl_version")
اگر نسخه == "":
سرچاپ "این اتصال رمزنگاری نشده است"
وگرنه:
سرچاپ "رمزنگاری با"، نسخه، "و رمز"، وضعیت(پ، "Ssl_cipher")
پایان
برگشت ۰
پایانهمین برنامه با رمزنگاری خاموش:
SALAM_MYSQL_SSL_MODE=DISABLED ./guide-tls
SALAM_MYSQL_SSL_MODE: DISABLED
این اتصال رمزنگاری نشده است
هر وقت پایگاه داده روی ماشین دیگری است VERIFY_IDENTITY را با یک فایل CA به کار ببرید. بدون بررسی گواهی، TLS ترافیک را از کسی که گوش میدهد پنهان میکند، ولی نه از کسی که میتواند خودش را جای سرور جا بزند.
کدام تابع برای کدام کار
| کار | تابع |
|---|---|
| وصل شدن و بررسی | بازکردن، سپس معتبر و خطا؛ در پایان بستن |
| اجرای دستوری که ردیف برنمیگرداند | اجرا، سپس ردیف های تحت تاثیر و شناسه آخرین درج |
| یک عدد یا یک متن | پرسمان عدد، پرسمان متن |
| چند ردیف | پرسمان، پرسمان معتبر، حلقه روی بعدی، سپس پایان |
| مقداری از کاربر | پ.نقل قول، یا اسکیپ درون نقلقولهایی که خودتان مینویسید |
| جدا کردن NULL از خالی | خالی است |
| چند نوشتن با هم | شروع تراکنش، ثبت تراکنش، بازگردانی، یا در تراکنش |
| چرا دستوری شکست خورد | کدخطا و خطا |
| کدی که روی هر پایگاه دادهای کار کند | اتصال و تابعهای دیتابیس |
| سرور هنوز هست؟ | پینگ |
آماده سازی کتابخانه، پایان کتابخانه، آماده سازی نخ و پایان نخ فقط برای این هستند که کد منتقلشده از API زبان C کامپایل شود؛ این کارخواه به هیچ کدام نیاز ندارد. بازکردن کامل پرچمهای اضافهی کارخواه را میگیرد، ولی آرگومان سوکت آن باید خالی باشد، چون اتصال فقط از راه TCP است.
گونهها
پایگاه داده Database
ساختار پایگاه داده| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| دسته | handle | تهی* | اشارهگر حالت اتصال. |
واردسازی دیتابیس
واردسازی دیتابیس.مای اس کیو ال
تابع ریشه:
اگر وارونه مای اس کیو ال.در دسترس():
سرچاپ "کارخواه MySQL در دسترس نیست"
برگشت
پایان
_ := مای اس کیو ال.آماده سازی کتابخانه()
_ := مای اس کیو ال.آماده سازی نخ()
سرچاپ مای اس کیو ال.نسخه کلاینت()
پ := مای اس کیو ال.بازکردن("127.0.0.1"، "app"، "s3cret"، "shop"، ۳۳۰۶)
اگر وارونه مای اس کیو ال.معتبر(پ):
سرچاپ مای اس کیو ال.کدخطا(پ)، مای اس کیو ال.خطا(پ)
برگشت
پایان
سرچاپ مای اس کیو ال.نسخه سرور(پ)، مای اس کیو ال.پینگ(پ)
_ := مای اس کیو ال.تنظیم کدینگ(پ، "utf8mb4")
_ := مای اس کیو ال.انتخاب پایگاه داده(پ، "shop")
نام := مای اس کیو ال.اسکیپ(پ، "O'Brien")
_ := مای اس کیو ال.اجرا(پ، "INSERT INTO customers (name) VALUES ('" + نام + "')")
سرچاپ مای اس کیو ال.شناسه آخرین درج(پ)، مای اس کیو ال.ردیف های تحت تاثیر(پ)، مای اس کیو ال.تعداد تغییرات(پ)
_ := مای اس کیو ال.ثبت خودکار(پ، نادرست)
_ := مای اس کیو ال.شروع تراکنش(پ)
_ := مای اس کیو ال.اجرا(پ، "UPDATE products SET stock = stock - 1 WHERE id = 7")
اگر مای اس کیو ال.پرسمان عدد(پ، "SELECT stock FROM products WHERE id = 7") < ۰:
_ := مای اس کیو ال.بازگردانی(پ)
وگرنه:
_ := مای اس کیو ال.ثبت تراکنش(پ)
پایان
ناپایا ن := مای اس کیو ال.پرسمان(پ، "SELECT id, name, price, note FROM products")
اگر مای اس کیو ال.پرسمان معتبر(ن):
سرچاپ مای اس کیو ال.تعداد ستون(ن)، مای اس کیو ال.تعداد ردیف(ن)، مای اس کیو ال.نام ستون(ن، ۱)
سرچاپ مای اس کیو ال.نوع فیلد(ن، ۰)، مای اس کیو ال.نوع داده فیلد(ن، ۲) == دیتابیس.نوع اعشاری
تا مای اس کیو ال.بعدی(ن):
سرچاپ مای اس کیو ال.عدد صحیح(ن، ۰)، مای اس کیو ال.متن(ن، ۱)، مای اس کیو ال.عدد اعشار(ن، ۲)، مای اس کیو ال.عدد صحیح۶۴(ن، ۰)، مای اس کیو ال.خالی است(ن، ۳)، مای اس کیو ال.نوع ستون(ن، ۳) == دیتابیس.نوع خالی
پایان
مای اس کیو ال.پایان(ن)
پایان
سرچاپ مای اس کیو ال.پرسمان متن(پ، "SELECT VERSION()")
ا := مای اس کیو ال.اتصال(پ)
سرچاپ ا.نوع()، دیتابیس.پرسمان عدد(ا، "SELECT COUNT(*) FROM products")
سرچاپ پ.نوع()، پ.پینگ()، پ.نقل قول("x'y")
ر := پ.پرسمان("SELECT name FROM customers")
تا ر.بعدی():
سرچاپ ر.متن(۰)
پایان
_ := ر.بستن()
مای اس کیو ال.بستن(پ)
مای اس کیو ال.پایان نخ()
مای اس کیو ال.پایان کتابخانه()
_ := مای اس کیو ال.بازکردن کامل("localhost"، "app"، "s3cret"، "shop"، ۰، "/tmp/mysql.sock"، ۰ برگردان طبیعی۶۴)
پایاننوع Kind
تابع نوع(): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
معتبر Ok
تابع معتبر(): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پینگ Ping
تابع پینگ(): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
اجرا Exec
تابع اجرا(sql: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پرسمان Query
تابع پرسمان(sql: رشته): dyn db.Rowsنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
شروع تراکنش Begin
تابع شروع تراکنش(): dyn db.Txنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
شناسه آخرین درج LastInsertId
تابع شناسه آخرین درج(): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
تعداد تغییرات Changes
تابع تعداد تغییرات(): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
خطا Error
تابع خطا(): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نقل قول Quote
تابع نقل قول(s: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
بستن Close
تابع بستن(): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نتیجه Result
ساختار نتیجه| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| دسته | handle | تهی* | اشارهگر نتیجه. |
| ردیف | row | تهی* | ردیف جاری. |
نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
معتبر Ok
تابع معتبر(): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
بعدی Next
تابع بعدی(): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
تعداد ستون ColumnCount
تابع تعداد ستون(): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نام ستون ColumnName
تابع نام ستون(col: صحیح): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نوع ستون ColumnType
تابع نوع ستون(col: صحیح): صحیحنوع خالی و گرنه نوع متن، چون سرور همهی مقدارها را به شکل متن میفرستد؛ نگاه کنید به دیتابیس.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
خالی است IsNull
تابع خالی است(col: صحیح): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
متن Text
تابع متن(col: صحیح): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
عدد صحیح Int
تابع عدد صحیح(col: صحیح): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
عدد صحیح۶۴ Int64
تابع عدد صحیح۶۴(col: صحیح): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
عدد اعشار Float
تابع عدد اعشار(col: صحیح): اعشار۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
بستن Close
تابع بستن(): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
تراکنش Txn
ساختار تراکنش| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| دسته | handle | تهی* | اشارهگر اتصال. |
نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
معتبر Ok
تابع معتبر(): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
اجرا Exec
تابع اجرا(sql: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پرسمان Query
تابع پرسمان(sql: رشته): dyn db.Rowsنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
ثبت تراکنش Commit
تابع ثبت تراکنش(): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
بازگردانی Rollback
تابع بازگردانی(): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
تابعها
در دسترس Available
تابع در دسترس(): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نسخه کلاینت ClientVersion
تابع نسخه کلاینت(): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نسخه سرور ServerVersion
تابع نسخه سرور(db: پایگاه داده): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
بازکردن Open
تابع بازکردن(host: رشته، user: رشته، pass: رشته، dbname: رشته، port: صحیح): پایگاه دادهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
بازکردن کامل OpenFull
تابع بازکردن کامل(host: رشته، user: رشته، pass: رشته، dbname: رشته، port: صحیح، socket: رشته، flags: طبیعی۶۴): پایگاه دادهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
معتبر Ok
تابع معتبر(db: پایگاه داده): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
بستن Close
تابع بستن(db: پایگاه داده)نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پینگ Ping
تابع پینگ(db: پایگاه داده): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
انتخاب پایگاه داده SelectDB
تابع انتخاب پایگاه داده(db: پایگاه داده، name: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
تنظیم کدینگ SetCharset
تابع تنظیم کدینگ(db: پایگاه داده، charset: رشته): صحیحSET NAMES را با کدگذاری دادهشده اجرا میکند؛ اتصال از ابتدا utf8mb4 است و فارسی را درست نگه میدارد، پس این فقط برای کدگذاری دیگری لازم است.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
خطا Error
تابع خطا(db: پایگاه داده): رشتهبازکردن ناموفق، دلیل شکست.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
کدخطا Errno
تابع کدخطا(db: پایگاه داده): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
اجرا Exec
تابع اجرا(db: پایگاه داده، sql: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
ردیف های تحت تاثیر AffectedRows
تابع ردیف های تحت تاثیر(db: پایگاه داده): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
تعداد تغییرات Changes
تابع تعداد تغییرات(db: پایگاه داده): صحیح۶۴ردیف های تحت تاثیر.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
شناسه آخرین درج LastInsertId
تابع شناسه آخرین درج(db: پایگاه داده): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
شروع تراکنش Begin
تابع شروع تراکنش(db: پایگاه داده): صحیحSTART TRANSACTION تراکنش آغاز میکند.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
ثبت تراکنش Commit
تابع ثبت تراکنش(db: پایگاه داده): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
بازگردانی Rollback
تابع بازگردانی(db: پایگاه داده): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
ثبت خودکار Autocommit
تابع ثبت خودکار(db: پایگاه داده، enabled: منطقی): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پرسمان Query
تابع پرسمان(db: پایگاه داده، sql: رشته): نتیجهپرسمان معتبر بسنجید.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پرسمان معتبر QueryOk
تابع پرسمان معتبر(res: نتیجه): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
بعدی Next
تابع بعدی(res &: نتیجه): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پایان Finish
تابع پایان(res: نتیجه)نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
تعداد ستون ColumnCount
تابع تعداد ستون(res: نتیجه): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
تعداد ردیف RowCount
تابع تعداد ردیف(res: نتیجه): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نام ستون ColumnName
تابع نام ستون(res: نتیجه، col: صحیح): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نوع فیلد FieldType
تابع نوع فیلد(res: نتیجه، col: صحیح): صحیحINT، ۸ برای BIGINT، ۵ برای DOUBLE، ۲۴۶ برای DECIMAL و ۲۵۳ برای VARCHAR؛ اگر پرسمان نتیجهای نداده باشد ۰.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نوع داده فیلد FieldKind
تابع نوع داده فیلد(res: نتیجه، col: صحیح): صحیحنوع صحیح برای نوعهای عدد صحیح، نوع اعشاری برای FLOAT و DOUBLE، و نوع متن برای بقیه، از جمله DECIMAL؛ نگاه کنید به دیتابیس. به ردیف جاری نگاه نمیکند، پس برای خانهی NULL هم گونهی ستون را میدهد.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
نوع ستون ColumnKind
تابع نوع ستون(res: نتیجه، col: صحیح): صحیحنوع داده فیلد، با این تفاوت که اگر مقدار ستون در ردیف جاری NULL باشد نوع خالی میدهد.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
متن Text
تابع متن(res: نتیجه، col: صحیح): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
عدد صحیح Int
تابع عدد صحیح(res: نتیجه، col: صحیح): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
عدد صحیح۶۴ Int64
تابع عدد صحیح۶۴(res: نتیجه، col: صحیح): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
عدد اعشار Float
تابع عدد اعشار(res: نتیجه، col: صحیح): اعشار۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
خالی است IsNull
تابع خالی است(res: نتیجه، col: صحیح): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
اسکیپ Escape
تابع اسکیپ(db: پایگاه داده، s: رشته): رشته% و _ دست نمیخورند.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پرسمان عدد QueryInt
تابع پرسمان عدد(db: پایگاه داده، sql: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پرسمان متن QueryText
تابع پرسمان متن(db: پایگاه داده، sql: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
آماده سازی کتابخانه LibraryInit
تابع آماده سازی کتابخانه(): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پایان کتابخانه LibraryEnd
تابع پایان کتابخانه()نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
آماده سازی نخ ThreadInit
تابع آماده سازی نخ(): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
پایان نخ ThreadEnd
تابع پایان نخ()نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam
اتصال Conn
تابع اتصال(d: پایگاه داده): dyn db.Connectionاتصال مشترک برمیگرداند.نمونهی این مورد همراه با موارد بالاتر آمده است: db-mysql-Client.salam