Aduino - MSSQL

params.port = 14333; bu değeri params.port = 1433; şeklinde güncellerseniz muhtemelen çalışacaktır.
Evet portu yanlış yazmışım. Düzelttikten sonra bağlantı sağladım. Bazen göz önündeki şey bile gözden kaçabiliyor...

Bir kaç satırlık veri çekmeyi denediğimde farklı hatalar aldım ama bana lazım olan row count bilgisiydi zaten ve bunu alabildim. Şuan istediğim şeyi yapabiliyorum.

Kütüphane ve desteğiniz için çok teşekkür ederim :)
 
Merhaba mustafakemalgilor

SELECT komutu ile MSSQL'den veri okumak istiyorum. Bu okuduğum verileri nasıl ayrıştırabilirim ve serial ekranda gösterebilirim. Bununla ilgili bir örnek verebilirmisiniz.
 
Selamlar kumandan11,

Sorgu sonucunda gelen tablo verisini işlemek için `execute_query` fonksiyonuna bir callback fonksiyonu sağlamanız gerekli. Bu callback fonksiyonu çalıştırılan sorgunun sonucunda dönen tablonun her bir satırı için çağrılacaktır:

https://github.com/mustafakemalgilo...rduino/03-select-rows/03-select-rows.ino#L256
Yukarıdaki örnekte `execute_query` fonksiyonuna callback olarak `row_callback` fonksiyonu verilmiş. Sorgu sonuçları gelmeye başladığında `row_callback` fonksiyonu satır bilgisi ile çağrılacaktır:

https://github.com/mustafakemalgilo...rduino/03-select-rows/03-select-rows.ino#L229

Kod:
static void row_callback(void * u, const tdsl::tds_colmetadata_token & colmd,
                         const tdsl::tdsl_row & row) {
    SERIAL_PRINTLNF("row: %.4s %d", row [0].as<tdsl::char_view>().data(),
                    row [1].as<tdsl::int32_t>());
}

Bu fonksiyonun 2. argümanı olan `colmd` sütün bilgisi, 3. argümanı olan `row` ise satır bilgisidir. row[0], row[1] şekilnde satırın her bir hücresine erişebilirsiniz ve .as<...> fonskiyonunu kullanarak o hücreyi istediğiniz veri türünde okuyabilirsiniz, örneğin:

Kod:
# burada a: int, b: varchar, c: float olsun
driver.execute_query("SELECT a,b,c FROM #example_table", callback)

static void callback(
void * u, const tdsl::tds_colmetadata_token & colmd,
                         const tdsl::tdsl_row & row){
    tdsl::int32_t a = row[0].as<tdsl::int32_t>();
    tdsl::char_view b = row[1].as<tdsl::char_view>();
    float c = row[2].as<float>();
}
 
Cevabınız için teşekkür ederim.
Verilerin sadece baş harflerini okudum. as<tdsl::char_view>() olarak okuduğum için mi başarılı olamadım ? Türkçe karakter İNSERT veya okuma yapamadım.


C#:
static void row_callback(void * u, const tdsl::tds_colmetadata_token & colmd,
                         const tdsl::tdsl_row & row) {
  SERIAL_PRINTLNF("row: %s %s %s %s %s", row [0].as<tdsl::char_view>().data(),
                  row [1].as<tdsl::char_view>().data(),
                  row [2].as<tdsl::char_view>().data(),
                  row [3].as<tdsl::char_view>().data(),
                  row [4].as<tdsl::char_view>().data());
}

// --------------------------------------------------------------------------------

void loop() {
  // Your queries goes here.
  if(read_flag==1){
    database_read();
    read_flag=0;
  }
}

void database_read() {

  // Execute SELECT query on every tenth loop
    auto query{TDSL_PMEMSTR("SELECT TOP (3) Name,ID,Address,City,Country FROM rfid_user")};
    SERIAL_PRINTF("Executing query: ");
    SERIAL_PRINTLNF_PROGMEM(query.raw_data());
    // We're using the row
    auto result = driver.execute_query(query, row_callback);
    SERIAL_PRINTLNF("Rows affected: %d", result.affected_rows);

}

Serial Output:
Kod:
Initializing ethernet interface
Initializing tdslite
Executing query: SELECT TOP (3) Name,ID,Address,City,Country FROM rfid_user
row: U 1 O B T
row: S 3 D B T
row: S 6 E B T
Rows affected: 3

Olması gereken veri :
Kod:
Name    ID            Address        City    Country
UĞUR    11B41624    OSMANGAZI    BURSA    TÜRKIYE
SENA    325EEA45    DEMIRTAŞ    BURSA    TÜRKIYE
SİNAN    645E2FFC    EMEK        BURSA    TÜRKİYE

Database Tasarımı:
Kod:
Name     nvarchar(100)
ID         nvarchar(10)
Address     nvarchar(100)
City     nvarchar(50)
Country     nvarchar(50)

Database'i nvarchar yerine varchar olarak değiştirdim. Aşağıdaki gibi bir çıkış aldım.
row: U⸮UR 11B41624 OSMANGAZI BURSA T⸮RKIYE⸮
row: SENA 325EEA45 DEMIRTA⸮ BURSA T⸮RKIYE⸮
row: S⸮NAN 645E2FFC EMEK BURSA T⸮RK⸮YE⸮
 
Son düzenleme:
1) Okuduğumuz verileri varchar verilerini String bir değişkene nasıl aktarabiliriz. Okuduğum verileri farklı yerlerde kullanmak istiyorum.
2) Türkçe karakter okuma sorununun bir çözümü var mı ?

C:
static void row_callback(void * u, const tdsl::tds_colmetadata_token & colmd,
                         const tdsl::tdsl_row & row) {
  SERIAL_PRINTLNF("row: %s %s %s %s %s", row [0].as<tdsl::char_view>().data(),
                  row [1].as<tdsl::char_view>().data(),
                  row [2].as<tdsl::char_view>().data(),
                  row [3].as<tdsl::char_view>().data(),
                  row [4].as<tdsl::char_view>().data());
  // Verileri string değişkene atama              
  tdsl::char_view a = row[0].as<tdsl::char_view>();
  tdsl::char_view b = row[1].as<tdsl::char_view>();
  tdsl::char_view c = row[2].as<tdsl::char_view>();
  tdsl::char_view d = row[3].as<tdsl::char_view>();
  tdsl::char_view e = row[4].as<tdsl::char_view>();
  Name[10] = row[0].as<tdsl::char_view>();
  SERIAL_PRINTLNF("row: %s", a);
  SERIAL_PRINTLNF("row: %s", String(a));
  SERIAL_PRINTLNF("row: %s", Name);
  SERIAL_PRINTLNF("row: %s", String(Name));
}

Kod:
row: S⸮NAN 645E2FFC EMEK BURSA T⸮RK⸮YE⸮
row: ⸮
row:
row:
row:
Rows affected: 3
 
1) Okuduğumuz verileri varchar verilerini String bir değişkene nasıl aktarabiliriz. Okuduğum verileri farklı yerlerde kullanmak istiyorum.
2) Türkçe karakter okuma sorununun bir çözümü var mı ?

C:
static void row_callback(void * u, const tdsl::tds_colmetadata_token & colmd,
                         const tdsl::tdsl_row & row) {
  SERIAL_PRINTLNF("row: %s %s %s %s %s", row [0].as<tdsl::char_view>().data(),
                  row [1].as<tdsl::char_view>().data(),
                  row [2].as<tdsl::char_view>().data(),
                  row [3].as<tdsl::char_view>().data(),
                  row [4].as<tdsl::char_view>().data());
  // Verileri string değişkene atama              
  tdsl::char_view a = row[0].as<tdsl::char_view>();
  tdsl::char_view b = row[1].as<tdsl::char_view>();
  tdsl::char_view c = row[2].as<tdsl::char_view>();
  tdsl::char_view d = row[3].as<tdsl::char_view>();
  tdsl::char_view e = row[4].as<tdsl::char_view>();
  Name[10] = row[0].as<tdsl::char_view>();
  SERIAL_PRINTLNF("row: %s", a);
  SERIAL_PRINTLNF("row: %s", String(a));
  SERIAL_PRINTLNF("row: %s", Name);
  SERIAL_PRINTLNF("row: %s", String(Name));
}

Kod:
row: S⸮NAN 645E2FFC EMEK BURSA T⸮RK⸮YE⸮
row: ⸮
row:
row:
row:
Rows affected: 3

Selamlar,

Okuduğunuz sütün NVARCHAR türünde olduğu için sütunun collation türüne bağlı olmakla beraber her karakterin 2 byte uzunlukta olduğu UTF-16 veya UCS-2 encoding'e sahip. Dolayısıyla kodunuzu u16char_view kullanacak şekilde güncellemeniz, ve string türü kullanırken de "wide" string kullanmanız gerekiyor:

Kod:
  tdsl::u16char_view a = row[0].as<tdsl::u16char_view>();
  tdsl::u16char_view b = row[1].as<tdsl::u16char_view>();
  tdsl::u16char_view c = row[2].as<tdsl::u16char_view>();
  tdsl::u16char_view d = row[3].as<tdsl::u16char_view>();
  tdsl::u16char_view e = row[4].as<tdsl::u16char_view>();

Okuduğunuz veriyi string'e atamak ile alakalı ise, veriyi istediğiniz yere kopyalamanız gerekiyor:

Kod:
char buf[128] = {};
tdsl::char_view field = row[0].as<tdsl::char_view>();
memcpy(buf, field.data(), field.size_bytes());
buf[127] = '\0';
String s{buf};

... veya

Kod:
tdsl::char_view field = row[0].as<tdsl:::char_view>();
String s{field.data(), field.size_bytes()};
 
Son düzenleme:
Selamlar,

Okuduğunuz sütün NVARCHAR türünde olduğu için sütunun collation türüne bağlı olmakla beraber her karakterin 2 byte uzunlukta olduğu UTF-16 veya UCS-2 encoding'e sahip. Dolayısıyla kodunuzu u16char_view kullanacak şekilde güncellemeniz, ve string türü kullanırken de "wide" string kullanmanız gerekiyor:

Kod:
  tdsl::u16char_view a = row[0].as<tdsl::u16char_view>();
  tdsl::u16char_view b = row[1].as<tdsl::u16char_view>();
  tdsl::u16char_view c = row[2].as<tdsl::u16char_view>();
  tdsl::u16char_view d = row[3].as<tdsl::u16char_view>();
  tdsl::u16char_view e = row[4].as<tdsl::u16char_view>();

Okuduğunuz veriyi string'e atamak ile alakalı ise, veriyi istediğiniz yere kopyalamanız gerekiyor:

Kod:
char buf[128] = {};
tdsl::char_view field = row[0].as<tdsl::char_view>();
memcpy(buf, field.data(), field.size_bytes());
buf[127] = '\0';
String s{buf};

... veya

Kod:
tdsl::char_view field = row[0].as<tdsl:::char_view>();
String s{field.data(), field.size_bytes()};

Cevabınız için teşekkür ederim.
Database varchar olarak tanımlı. Türkçe karakterleri hala okuyamadım. Eksik yaptığım birşey var mı ?

C++:
static void row_callback(void * u, const tdsl::tds_colmetadata_token & colmd,
                         const tdsl::tdsl_row & row) {
  SERIAL_PRINTLNF("row: %s %s %s %s %s", row[0].as<tdsl::char_view>().data(),
                  row [1].as<tdsl::char_view>().data(),
                  row [2].as<tdsl::char_view>().data(),
                  row [3].as<tdsl::char_view>().data(),
                  row [4].as<tdsl::char_view>().data());

  // Verileri string değişkene atama
  char buf[128] = {};
  tdsl::char_view field = row[0].as<tdsl::char_view>();
  memcpy(buf, field.data(), field.size_bytes());
  buf[127] = '\0';
  String s{buf};

  Serial.println(s);
}

Kod:
Executing query: SELECT TOP (4) Name,ID,Address,City,Country FROM rfid_user
row: U⸮UR 11B41624     OSMANGAZ⸮ BURSA T⸮RK⸮YE⸮
U⸮UR
row: MUSTAFA DA⸮ 191B160E YILDIRIM BURSA T⸮RK⸮YE⸮
MUSTAFA DA⸮
row: SENA 325EEA45 DEM⸮RTA⸮ BURSA T⸮RK⸮YE⸮
SENA
row: S⸮NAN 645E2FFC EMEK BURSA T⸮RK⸮YE⸮
S⸮NAN
Rows affected: 4
 
Selamlar,

ASCII karakter seti Türkçe karakterleri kapsamıyor, bu nedenle ekrana yazdırırken Türkçe karakterlerin olduğu kısımlar "?" şeklinde gösteriliyor. Veride bir bozukluk yok, sadece gösterimde problem var. Karakterleri düzgün göstermek için veritabanında NVARCHAR sütun türü kullanmalı ve veriyi konsola yazdırırken uygun fonksiyonu kullanmalısınız (arduino serial sınıfı multi-byte karakter string print etmeyi destekliyor mu bilmiyorum).
 
Selamlar arkadaşlar!
Paylaştığınız `arduino-mssql` kütüphanenin yazarıyım, internette gezinirken konunuza rast geldim ve size ufak bir bilgilendirme yapmak istedim.

`arduino-mssql` kütüphanesi konseptin kanıtı (proof-of-concept) olarak yaptığım bir çalışmaydı, kısa süre önce kütüphanenin halefi olarak `tdslite` adlı yeni bir kütüphaneyi yayınladım. MSSQL'e bağlanmak için bu yeni kütüphaneyi kullanabilirsiniz. Kütüphaneyi Arduino Library Manager veya Platform IO Registry'da `tdslite` olarak aratarak bulabilirsiniz. Alternatif olarak, GitHub reposunda yayınlanan sürümlerden "zip" halini indirerek de kullanabilirsiniz.

Yeni kütüphane platform bağımsız bir yapıda olduğundan Arduino dışında bir çok board'da (örn. ESP, STM) da kullanabilirsiniz. Başlangıç örneği olarak https://github.com/mustafakemalgilo...les/arduino/03-select-rows/03-select-rows.ino bu örneği incelemenizi öneririm.

https://github.com/mustafakemalgilor/tdslite

Sağlıcakla kalın,
Mustafa
Merhaba mustafakemalgilor,

Kütüphanenizi kullanarak bende mssql bağlantısı kurup okuduğum sıcaklı basınç değerlerini DB kayıt etmek istiyorum ama bunun için arduino uno wifi 2 kullanıyorum siz örnekte esp ile vermişsiniz entegre WiFi olduğu için bir türlü DB bağlantısı sağlayamadım bu cihaz ile yapabilir miyim yoksa değiştirmem mi gerekiyor konu ile yardımcı olur musunuz.
 
Selamlar brsbnkc,

Kütüphaneyi Arduino Uno Wifi rev.2 ile de kullanabilirsin fakat esp için verdiğim örnek kodda ufak değişiklikler yapman gerekiyor. Boş vaktimde bir örnek eklemeye çalışacağım.
 

Forum istatistikleri

Konular
129,864
Mesajlar
930,851
Kullanıcılar
452,726
Son üye
ugur Göktürk

Yeni konular

Geri
Üst