Różny typ danych w koumnie, SQL

Odpowiedz Nowy wątek
2018-11-07 09:34
Szalony Ogórek
0

Cześć,

Mam problem z porównaniem zawartości kolumn w momencie jeśli w danej kolumnie znajdują się różne typy danych, np: "aaa" oraz "111"
Poniższy fragment kodu wybiera wszystko co znajduje sie w BAZA2 a czego nie ma w BAZA1, jednak jeśli w którejkolwiek z kolumn pojawią się różne typy danych, zwraca błąd.

"select * from BAZA2.csv baza_2 where not exists " & _
"(select * from BAZA1.csv baza_1 where " & _
"baza_1.kolumna_1 = baza_2.kolumna_1 and " & _
"baza_1.kolumna_2 = baza_2.kolumna_2 and " & _
"baza_1.kolumna_3 = baza_2.kolumna_3)"

Czy ktoś ma pomysł w jaki sposób można rozwiązać ten problem?

Pozostało 580 znaków

2018-11-07 09:46
2

Kolumna ma swój typ danych, porównując wartości w kolumnach o różnych typach dokonujesz niejawnej konwersji typów. Nie piszesz na jakim silniku pracujesz, ale to zagadnienie podchodzi pod data type precedence, dla mssql jest taki: https://docs.microsoft.com/en[...]sact-sql?view=sql-server-2017

Czyli jeżeli np.: baza_1.kolumna_1 to int, a baza_2.kolumna_1 to varchar to wg. kolejności silnik będzie się starał dokonać konwersji baza_2.kolumna_1 do typu int. to zadziała dopóki będzie się to dało zrobić.

rozwiązanie to dokonać konwersji typu samemu, np. tak:

convert(varchar(100),baza_1.kolumna_1)  = baza_2.kolumna_1
Przecież widać, że to Access :) - Marcin.Miga 2018-11-07 09:50
No nie do końca, w Access nadanie aliasu dla tabeli bez as wywali bląd... - Panczo 2018-11-07 09:52
Nie w kodzie VBA... A widać, że to VBA. - Marcin.Miga 2018-11-07 09:53
Możliwe, że Access, ale to odpowiedź nadal prawidlowa ;) dla OP-a konwersje w Access: https://support.office.com/en[...]4-2d43-4975-bb13-87ac8d1a2202 - Panczo 2018-11-07 09:58

Pozostało 580 znaków

2018-11-07 10:07
Szalony Ogórek
0

Nie jestem pewny jaki to silnik. Mój kod to VBScript w którym jest wpleciona kwerenda w SQL, wygląda to tak:


``` Set fso = CreateObject("Scripting.FileSystemObject")
``` Set shell = CreateObject("WScript.Shell")
``` If Instr(WScript.FullName, "\System32\") And fso.FolderExists("C:\Windows\SysWow64") Then
```     shell.Run "C:\Windows\SysWow64\wScript.exe  """ & wscript.scriptFullName & """"
```     Wscript.quit
``` End If
```'
``` Dim polacz  
``` Const adOpenStakwerenda = 3
``` Const adLockOptimiskwerenda = 3
``` Const adCmdText = &H0001
``` Dim fullPath
``` fullPath = fso.GetParentFolderName(fso.GetFile(Wscript.ScriptFullName))
```'    
``` Set objExcel = CreateObject("Excel.Application")
``` objExcel.Visible = False
``` objExcel.DisplayAlerts = False
```'
``` Set polacz = CreateObject("ADODB.Connection")
``` polacz.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & fullPath & ";" & "Extended Properties=""text;HDR=YES;FMT=Delimited"""    
```'            
``` Set rekord = CreateObject("ADODB.Recordset")
```'    
```'<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
```'<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
```kwerenda = "select * from BAZA2.csv baza_2 where not exists " & _
``` "(select * from BAZA1.csv baza_1 where " & _
``` "baza_1.kolumna_1 = baza_2.kolumna_1 and " & _
``` "baza_1.kolumna_2 = baza_2.kolumna_2 and " & _
``` "baza_1.kolumna_3 = baza_2.kolumna_3)"
```'<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
```'<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
```'
``` rekord.Open kwerenda, polacz, adOpenStakwerenda, adLockOptimiskwerenda, adCmdText 
```'
``` Set OutputFile = fso.CreateTextFile(fullPath & "\wynik.js")
```'
``` i=0 
```'
``` Do Until rekord.eof
```     OutputFile.WriteLine("kwerenda[" & i & "]={" & _
```                 chr(34) & "znaleziony rekord" & chr(34) & ":" & _
```                 chr(34) & rekord.fields.item("kolumna_1") & chr(34) & "," & _
```                 chr(34) & rekord.fields.item("kolumna_2") & chr(34) & "," & _
```                 chr(34) & rekord.fields.item("kolumna_3") & chr(34) & _
```     "};")
```'        
```     i=i+1
```     rekord.movenext 
``` Loop
```'
``` rekord.Close
``` OutputFile.Close
```'    
``` objExcel.Quit
Provider=Microsoft.Jet.OLEDB.4.0 JET czyli Access :) - Marcin.Miga 2018-11-07 10:23

Pozostało 580 znaków

2018-11-07 10:24
0

Używasz JET-a Accessowego do pobrania danych z 2 plików CSV: baza1.csv i baza2.csv i generujesz plik wynik.js, pomijam fakt, że nie mam pojęcia po co jest w nim tworzona instancja Excela...

Sam kwerenda powinna wyglądać mniej więcej tak:

kwerenda = "select * from BAZA2.csv baza_2 where not exists " & _
"(select * from BAZA1.csv baza_1 where " & _
"cstr(baza_1.kolumna_1) = cstr(baza_2.kolumna_1) and " & _
 "cstr(baza_1.kolumna_2) = cstr(baza_2.kolumna_2) and " & _
 "cstr(baza_1.kolumna_3) = cstr(baza_2.kolumna_3))"
Myślę, że dla JET-a lepszy były LEFT JOIN z Nullem - Marcin.Miga 2018-11-07 10:39
Zdecydowanie. - Panczo 2018-11-07 10:42

Pozostało 580 znaków

2018-11-07 10:31
Szalony Ogórek
0

Instancja Excela jest tworzona na potrzeby pozostałego fragmentu kodu który skasowałem przed wklejeniem do tego posta (żeby nie wprowadzać niepotrzebnych elementów) - a zapomniałem skasować tworzenie obiektu :)

Dziękuję Ci bardzo za pomoc

Pozostało 580 znaków

2018-11-07 10:52
Szalony Ogórek
0

Ale obawiam się, że to rozwiązanie nie do końca pomogło :(
Wskazuje błąd "Invalid use of Null"
w linii
rekord.Open kwerenda, polacz, adOpenStakwerenda, adLockOptimiskwerenda, adCmdText

Pozostało 580 znaków

2018-11-07 10:58
0
kwerenda = "select * from BAZA2.csv baza_2 where not exists " & _
"(select * from BAZA1.csv baza_1 where " & _
"cstr(nz(baza_1.kolumna_1,"""")) = cstr(nz(baza_2.kolumna_1,"""")) and " & _
 "cstr(nz(baza_1.kolumna_2,"""")) = cstr(nz(baza_2.kolumna_2,"""")) and " & _
 "cstr(nz(baza_1.kolumna_3,"""")) = cstr(nz(baza_2.kolumna_3,"""")))"

Pozostało 580 znaków

2018-11-07 11:02
Szalony Ogórek
0

A za co odpowiada funkcja "nz"? Jest jak jak sie okazuje niezdefiniowana.

Pozostało 580 znaków

2018-11-07 11:11
0

Zamienia null na co chcesz, w przypadku co podał @Panczo na pusty string.

https://support.office.com/en[...]9-cc9c-438b-860a-7fd9f4c69b6c

Pozostało 580 znaków

2018-11-07 11:16
1

Faktycznie nz zadziała jak wywolasz w access, w przypadku ado trzeba użyć iif:

kwerenda = "select * from BAZA2.csv baza_2 where not exists " & _
"(select * from BAZA1.csv baza_1 where " & _
"iif(isnull(baza_1.kolumna_1),"""",cstr(baza_1.kolumna_1)) = iif(isnull(baza_2.kolumna_1),"""",cstr(baza_1.kolumna_1)) and " & _
 "iif(isnull(baza_1.kolumna_2),"""",cstr(baza_1.kolumna_2)) = iif(isnull(baza_2.kolumna_2),"""",cstr(baza_1.kolumna_3)) and " & _
 "iif(isnull(baza_1.kolumna_3),"""",cstr(baza_1.kolumna_3)) = iif(isnull(baza_2.kolumna_3),"""",cstr(baza_1.kolumna_3)))"
Pokaż pozostałe 2 komentarze
A w tym wypadku jak bierze dane z Excela w sumie co będzie lepsze? Zdaje się ze coś kiedyś czytałem że gdy odnosimy się do danych w samej bazie Access to lepsze jest DAO ale jak już działamy na zewnętrznych źródłach danych to już optymalniejsze jest ADO (oczywiście dla małych danych to nie robi ... różnica pojawiła by się pewnie przy dużych zbiorach). - BlackBad 2018-11-07 11:26
Ale on tu nie pobiera danych ani z Excela, ani z Accessa. "Czyta" CSV - Panczo 2018-11-07 11:30
Podobnei zresztą jak wszystkie funkcje VBA - w Access mogą być użyte, w JET nie :) - Marcin.Miga 2018-11-07 11:38

Pozostało 580 znaków

2018-11-07 11:30
Szalony Ogórek
0

Moje docelowe bazy które będę porównywał mają po ok 600-700 tyś rekordów, każdy składający się z 10 kolumn. W kolumnach będzie od 2 do max 300 znaków...

Oblicz sobie jakąś funkcję skrótu (np. md5, albo coś szybszego) dla CAŁEGO rekordu i po tym łącz. Bo ci Access umrze... - Marcin.Miga 2018-11-07 11:40

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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