Sprawdzanie typu zmiennej. Baza danych

0

Witam,

Piszę aplikację, która ma działać na bazie MySQL. Na bazie tej nie ma typu Boolean, jest jedynie TinyInt.
Jak łatwo się domyśleć wartość 0 to False, wartość inna to True.
Problem w tym, że w kodzie oczywiście używam Boolean.

Podczas Inserta danych muszę jednak przekonwertować tę wartość do int-a.
W jaki sposób zrobić to estetycznie? Taka konwersja może dotyczyć wielu danych (np. dat), więc mam użyć switcha?
Trochę mi się to nie podoba. Jest inny - ładniejszy sposób?

Pozdrawiam.

0

a jakby tak się zastanowić... to przecież Boolean to true i false, a true i false to 0,1. I jakby tą wartość w stawiać do tabulki ?

0

Tak masz rację, ale co w przypadku gdy masz typy danych, których tak nie da się zapisać?
Np. format daty, który na każdej bazie może inaczej chcieć się zapisać. Wtedy konwersja i tak będzie konieczna.

Nie ma sensu, więc zapisywać boolean jako int, tylko planuję napisać konwersję. Z myślą o innych typach danych i o przyszłości.

0

nie bardzo rozumiem co chcesz zrobić. jak masz typ boolean to masz typ boolean. Chyba że chcesz mieć w tabelce jedną kolumne to którego wrzucasz wszystko jak leci (nie patrzysz na boolean, date, int) to wtedy VARCHAR(50)

0

Chyba nie rozumiesz problemu.
Po 1.)
W MySQL nie ma czegoś takiego jak Boolean.

Po 2.)
Mam w kodzie napisaną uniwersalną metodę do SQL. Wygląda to tak:

        protected override void Save(object obj, object[] parameter)
        {
            DBControl.ExecuteNonQuery("INSERT INTO " + this.nameTable + " (" +
                this.GetColumnNames() + ") VALUES (" + this.GetValuesNames(parameter) + ")");
            ((IdentifyData)obj).ID = Convert.ToInt32(DBControl.ExecuteScalar(@"Select max(id) from " + this.nameTable));
        }

Po 3.)
Skoro nie ma odpowiedniego typu na bazie, to muszę wykonać konwersję. Jawną lub nie, ale nadal konwersję.

Po 4.)
Konwersja może być różna od bazy danych, gdyż nie na każdej dane są zapisywane tak samo. Przykładowo na Oracle jest Boolean, a na MySQL już nie.

1

Nie możesz jakiegoś ORMa użyć (albo czegoś ORMo-podobnego) jak masz wspierać kilka baz danych?
Np. http://simplefx.org/simpledata/docs/ czy http://nhforge.org/

0

Chciałem napisać po swojemu, nie korzystać z cudzych narzędzi.
Jednak to tylko moje "widzimisię" i realnych przesłanek, by nie korzystać z zewnętrznych narzędzi nie ma.

1
Złoty Szczur napisał(a):

Chyba nie rozumiesz problemu.
[...]
Mam w kodzie napisaną uniwersalną metodę do SQL. Wygląda to tak:

        protected override void Save(object obj, object[] parameter)
        {
            DBControl.ExecuteNonQuery("INSERT INTO " + this.nameTable + " (" +
                this.GetColumnNames() + ") VALUES (" + this.GetValuesNames(parameter) + ")");
            ((IdentifyData)obj).ID = Convert.ToInt32(DBControl.ExecuteScalar(@"Select max(id) from " + this.nameTable));
        }

Po prostu ludziom się nie mieści w głowach, że można takie potworki tworzyć. Po pierwsze zrób tak aby używać parametrów - problem z typami danych odpadnie. Po drugie generowanie UNIKALNEGO id jako SELECT Max(id) ... to jest WTF pierwszego sortu

0

Co masz na myśli "Używać parametrów". Przecież tam są wykorzystane parametry. Masz na myśli parametry z różnymi typami danych? To dopiero byłby WTF.

Kod powyżej był testowy wygląda teraz nieco inaczej. Niemniej ID nie jest przecież programistycznie nadawany, a jedynie piobierany. Przecież jest auto_increment ustawiony, a ja po insercie jedynie pobieram dane.

Problem rozwiązałem póki co moimi konwersjami, potem do tego dodam pliki konfiguracyjne i będzie ładnie.

0
Złoty Szczur napisał(a):

Co masz na myśli "Używać parametrów". Przecież tam są wykorzystane parametry. Masz na myśli parametry z różnymi typami danych? To dopiero byłby WTF.

Nie, nie używasz parametrów.

Tak się używa parametrów w SqlCommand:

string commandText = "UPDATE Table SET Column1 = @column1 " + "WHERE Column2 = @column2;";

using (SqlConnection connection = new SqlConnection(connectionString))
{
    SqlCommand command = new SqlCommand(commandText, connection);

    command.Parameters.AddWithValue("@column1", 'coś');

    command.Parameters.Add("@column2", SqlDbType.Int);
    command.Parameters["@column2"].Value = 'coś innego';

    connection.Open();
    command.ExecuteNonQuery();
}
0

Zamiast wplatać w zapytania bezpośrednio stringi używaj parametrów tak jak to wspomniał kolega wyżej. Te zapytanie to tak jak powiedział abrakadaber to jest taki potworek, że nawet ciężko mi ogarnąć go, strasznie ciężko się to czyta, a w razie błędów bardzo trudno jest go znaleźć. Pomyśl, że za kilka miesięcy będziesz chciał coś zmienić w tej aplikacji i zobaczysz takie zapytanie i kompletnie się pogubisz - wierz mi :) Ale ogólnie chodzi, żeby zamiast takiego zapytania:

DBControl.ExecuteNonQuery("INSERT INTO " + this.nameTable + " (" +
                this.GetColumnNames() + ") VALUES (" + this.GetValuesNames(parameter) + ")");
            ((IdentifyData)obj).ID = Convert.ToInt32(DBControl.ExecuteScalar(@"Select max(id) from " + this.nameTable));

zamiast np:

+ this.nameTable +

używać parametrów:

cmd.Parameters.AddWithValue("@nameTable", this.nameTable);

Wtedy w zapytaniu masz takie coś:

"INSERT INTO @nameTable

Jest to bezpieczniejsze, gdyż nie przekazujesz do zapytania bezpośrednio wartości, tylko poprzez parametr, no i ładniej wygląda same zapytanie :)

Aczkolwiek używaj ORM-a, super elastyczność, uniwersalność (nie ma znaczenia baza) i gdybyś chciał złączyć kilka tabel w zapytaniu, to zobaczysz wtedy czemu to jest przyjemność :)

0

Aaaach już rozumiem :)
No tak, zapomniałem, że coś takiego istnieje. Ok bardzo dziękuję, musze neico przepisać kodu, ale będzie dużo lepiej.

Zupełnie o tym zapomniałem.

0
Złoty Szczur napisał(a):

Co masz na myśli "Używać parametrów". Przecież tam są wykorzystane parametry. Masz na myśli parametry z różnymi typami danych? To dopiero byłby WTF.

tak włąśnie to mam na myśli. I byłby to kawałek poprawnego kodu a nie to co teraz. c# ma rozwinięty system refleksji więc nie jest problemem sprawdzić jaki typ danych przekazujesz i na tej podstawie przekazać odpowiedni typ parametru. Ile tych typów będziesz miał? Z 5 (int, double, string, datetime, bool). Na pewno będzie to bardziej profesjonalne i przede wszystkim bezpieczniejsze od konwersji wszystkiego do stringa.

Kod powyżej był testowy wygląda teraz nieco inaczej. Niemniej ID nie jest przecież programistycznie nadawany, a jedynie piobierany. Przecież jest auto_increment ustawiony, a ja po insercie jedynie pobieram dane.
jest coś takiego jak last_insert_id

0

A może chłopak chce sobie napisać własnego mappera. Jest to ogólnie doświadczenie pozwalające bardzo dużo się nauczyć. Zarówno o szczegółach .Net, DBMS, które ma się zamiar wspierać.
@XardasLord akurat nazwę tabeli trzeba wstawić przez sklejanie stringów/formatowanie, to samo dotyczy nazw kolumn (a przynajmniej trzeba było 2-3 lata temu przy składaniu zapytań dla SQL Servera). Parametry są świetne do przekazywania wartości pól, zrzucają z programisty ciężar myślenia o poprawnym przekodowaniu oraz znakach ucieczki.
Co do zapytania wyciągającego wartość klucza głównego. Select max po insercie rzeczywiście jest średnim pomysłem. Jednak wyciągnięcie wartości klucza głównego przed insertem przy pomocy zapytania jest uzasadnione np. dla systemu rozproszonego w którym stosuje się pule identyfikatorów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1