Làm việc với MSSQL trong Ruby với gem Tiny_tds

Trong bài viết này mình xin giới thiệu đến các bạn gem Tiny_tds để làm việc với MSSQL server trong dự án Ruby.

Cài đặt.

Trước tiên, phải cài đặt FreeTDS, với MacOS thì chỉ cần chạy lệnh đơn giản thế này:

brew install freetds

Sau khi cài đặt xong thì có thể kiểm tra bằng lệnh tsql -C hoặc thử kết nối đến database (có thể là ở dưới local hoặc là trên server đều được) qua command.

tsql -H <your_db_host> -p <your_db_port> -U <your_user_name> -P <your_password>

Tương tự với các OS khác, bạn có thể tham khảo tại đây.

Với Ruby, bạn cũng cần phải cài thêm gem tiny_tds nữa nhé.

Kiểu dữ liệu.

Cũng tương tự như MySQL, ngoài ra còn có các kiểu dữ liệu về thời gian như datetime2, datetimeoffset,... API này bao gồm cá lớp sau TinyTds::Client - kết nối của người dùng đến database. TinyTds::Result - kết quả trả về sau khi thực thi (execute) lệnh, nó bao gồm Enumerable. TinyTds::Error - chứa các ngoại lệ của FreeTDS.

TinyTds::Client.

Để kết nối tới database.

client = TinyTds::Client.new(username: "username", password: "password", host: "yourhost")

Ngoài các thuộc tính trên thì cũng có thể khai báo client với nhiều thuộc tính khác như: :port - mặc định là 1433. :login_timeout - thời gian chờ kết nối, mặc định là 60s. ... Có thể kiểm tra tình trạng kết nối của bạn bằng phương thức active?, dead?, closed? => trả về true/false. Và gọi hàm exectute từ client để thực hiện truy vấn lên server để trả về kết quả. Ví dụ đơn giản:

result = client.execute(SELECT * FROM [table_name])

TinyTds::Result.

Như trên ví dụ trên, thì đây là lớp sau khi thực thi câu lệnh từ client bên trên sẽ trả về. Một số câu lệnh đơn giản như sau:

result = client.execute(SELECT * FROM [cars];)
result.do

result = client.execute(INSERT INTO [cars] ([name], [color]) VALUES ((CX5, ‘white’), (Mazda3, ‘black’’)))
result.insert

result = client.execute(DELETE FROM [cars] WHERE [id] =1’”)
resutl.do

Bạn có thể xem thêm chi tiết về gem tiny_tdslink github nhé.


Dưới đây mình xin trình bày một chút code nhỏ để bạn dễ hình dung.

Trước tiên máy của bạn phải cài đặt Microsoft SQL Server (với Ubuntu thì phải từ bản 16.04 trở lên mới cài được, những bản cũ hơn thì phải cài qua máy ảo), và FreeTDS như mình có nhắc đến bên trên. Mình đang dùng MacOS Sierra và Azure SQL database. Bạn có thể cài đặt (SQLPro)[https://www.macsqlclient.com/] để quản lý csdl sql server, nó tương tự như là MySQL Workbench vậy.

Azure SQL Database is a relational database-as-a service using the Microsoft SQL Server Engine. SQL Database is > a high-performance, reliable, and secure database you can use to build data-driven applications and websites in > the programming language of your choice, without needing to manage infrastructure. Learn how to use SQL Database > with our quickstarts, tutorials, and samples.

Xem thêm về Azure SQL tại đây

Để Ruby làm việc được với MSSQL thì chúng ta cần cài đặt 2 gem này

gem "tiny_tds"
gem "activerecord-sqlserver-adapter"

File config/database.yml sẽ như thế này.

default: &default
  adapter: sqlserver
  azure: true

development: &development
  <<: *default
  host:     "database_host"
  database: "database_name"
  username: "database_user"
  password: "database_pass"

Với một database MSSQL sẵn (có thể là dưới local hoặc là trên server), bạn có thể tạo ra các file model để làm việc giống như là trước nay làm việc với ActiveRecord vậy. Làm việc kiểu này thì bạn không cần phải tạo file migration để migrate database nữa (vì db của bạn đã được thiết kế sẵn rồi).

class AzureRecord < ActiveRecord::Base
  self.abstract_class = true

  include AzureTime  
end
class Car < AzureRecord
  self.abstract_class = true

  self.table_name = :cars
end

Ở model Car trên, mình đã định nghĩa nó tương ứng với bảng products trên database.

[1] pry(main)> Car.connection
=> #<ActiveRecord::ConnectionAdapters::SQLServerAdapter version: 5.1.0, mode: dblib, azure: true>
[2] pry(main)> Car.count
   (2.9ms)  SELECT COUNT(*) FROM [cars]
=> 3

Và mình thấy có một thứ rất hay trong MSSQL đó chính là thủ tục stored procedure.

Tạo một thủ tục đơn giản như sau trong SQLPro và thực thi.

USE your_database;
GO

CREATE PROCEDURE [dbo].[getListCarsByColor]
    @Color nvarchar(50)
AS

    SET NOCOUNT ON;
    SELECT [name], [color] 
    FROM [dbo].[cars]
    WHERE [color] = @Color;
GO

Bạn sẽ tạo ra một thủ tục có tên là getListCarsByColor với tham số truyền vào là Color. Từ Ruby, ta có thể gọi đến thủ tục vừa khai báo ở trên như sau:

result = ActiveRecord::Base.execute_procedure(“dbo.getListCarsByColor”, Color: “black”)

Và thủ tục đó sẽ list ra danh sách ô tô có màu đen.

Như bạn đã thấy, với việc sử dùng MSSQL thế này, dev sẽ không cần phải quan tâm đến việc migrate db như trước kia, thậm chí như với thủ tục thì dev cũng không cần quan tâm đến các bảng trong db nó như thế nào, chỉ việc gọi đến thủ tục, truyền param vào là xong, có ngay kết quả.

Như vậy đôi khi cũng hay nhưng nhiều khi cũng dở nhỉ 😄.


Cảm ơn bạn đã theo dõi bài viết này!

All Rights Reserved