Zachowanie porządku przy wprowadzaniu calych tabel w MSSQL

0

Załóżmy, że mam dwie tabele. Tabela A zawiera pola P1, P2, P3, P4, tabela B zawiera AutoId, Q1, Q2, Q3, Q4. Pole AutoId jest automatycznie numerowanym identyfikatorem, a pozostałe są varchar.

Załóżmy, że potrzebuję dane z tabeli A sortowane w określonej kolejności

select P1, P2, P3, P4 from A order by P2, P1, P4 desc, P3

Mogę zrobić takie przepisanie danych z A do B

insert into B (Q1, Q2, Q3, Q4)
select P1, P2, P3, P4 from A order by P2, P1, P4 desc, P3

Z tabeli B pobiorę dane za pomocą takiego zapytania:

select Q1, Q2, Q3, Q4 from B order by AutoId

Czy przedstawiony sposób przepisania danych w połączeniu z autonumerem gwarantuje, że wiersze tabeli B sortowane według autonumeru są w tej samej kolejności, jaka była określona w poleceniu przepisującym dane? Jakbym utworzył kursor i wprowadzał po jednym wierszu, to z całą pewnością tak, ale czy również tak będzie przy wprowadzaniu całej tabeli?

2

nie prościej założyć indeks na tych polach? A co będzie jak dojdzie nowy wiersz, który będzie miał być gdzieś w środku? Jak już pisałem nie raz pole ID NIE SŁUŻY DO NUMEROWANIA REKORDÓW A DO JEDNOZNACZNEGO ICH IDENTYFIKOWANIA

0
abrakadaber napisał(a):

nie prościej założyć indeks na tych polach? A co będzie jak dojdzie nowy wiersz, który będzie miał być gdzieś w środku? Jak już pisałem nie raz pole ID NIE SŁUŻY DO NUMEROWANIA REKORDÓW A DO JEDNOZNACZNEGO ICH IDENTYFIKOWANIA

Oczywiście, że prościej założyć indeks klastrowany, który zapewnia sortowanie według pól indeksu. Tylko, że w MS SQL można założyć tylko jeden taki indeks na daną tabelę. Mi chodziło o działanie funkcji INSERT INTO.

W przypadku modyfikacji danych nowy wiersz będzie wpisany tylko do tabeli A, natomiast tabela B byłaby cyklicznie opróżniana i wypełniana. Nie szkodzi, że w tej sytuacji po modyfikacji w tabeli A, wiersze w tabeli B będą mieś przesunięte identyfikatory.

1

To niestety nie zadziała tak jak chcesz.Kolejność wierszy w żaden sposób nie będzie gwarantowana.To, że 100 razy sql server pokaże Ci to co chcesz, nie będzie oznaczało, że za 101 także dostaniesz to co chcesz.

Pozdrawiam ;-)

1
andrzejlisek napisał(a):

Czy przedstawiony sposób przepisania danych w połączeniu z autonumerem gwarantuje, że wiersze tabeli B sortowane według autonumeru są w tej samej kolejności, jaka była określona w poleceniu przepisującym dane?

Nie. Czytaj dokumentacje:

Specifying an ORDER BY clause does not guarantee the rows are inserted in the specified order.

http://msdn.microsoft.com/en-us/library/ms188029.aspx

Wiesz w ogóle czym jest indeks klastrowany i dlaczego może być jeden? Powinieneś mieć osobne pole na id (które nadawane jest raz, najlepiej generowane losowo - patrz NEWID(), jest niezmienne i identyfikuje zgodnie z nazwą dany wiersz w tabeli) i osobne pole na AutoNumber, który przechowuje ustaloną przez Ciebie kolejność. Dalej nie rozumiem jaki jest cel w istnieniu tutaj dwóch tabel. Po co chcesz tak przerzucać dane? Tylko dla uzyskania sortowania?

0
Vardamir napisał(a):

Wiesz w ogóle czym jest indeks klastrowany i dlaczego może być jeden? Powinieneś mieć osobne pole na id (które nadawane jest raz, najlepiej generowane losowo - patrz NEWID(), jest niezmienne i identyfikuje zgodnie z nazwą dany wiersz w tabeli) i osobne pole na AutoNumber, który przechowuje ustaloną przez Ciebie kolejność. Dalej nie rozumiem jaki jest cel w istnieniu tutaj dwóch tabel. Po co chcesz tak przerzucać dane? Tylko dla uzyskania sortowania?

Tu chodzi o upieczenie dwóch pieczeni na jednym ogniu. Sama replikacja danych bierze się stąd, że jest system ERP i B2B, system ERP działa na pewnych strukturach, raz dziennie ma odświeżać dane dla B2B poprzez wytwarzanie tabel o strukturach zoptymalizowanych pod B2B. Ponieważ replikacja danych i tak następuje, to jedna z nich ma postać taka, jak w pierwszym poście (oczywiście są inne nazwy pól i typy wartości), gdzie często z niej są uzyskiwane dane poprzez select pierwszej pozycji, która odpowiada pewnym warunkom z sortowaniem po kilku polach, za każdym razem według tego samego porządku. W testach okazało się, że wydajnościowo sortowanie po kilku polach nie jest problemem, ale miałem na myśli, żeby przy replikacji było jedno pole, którego sortowanie zapewni taki sam porządek, jak sortowanie po trzech polach w danych źródłowych.

Na podstawie powyższych odpowiedzi przyjmuję do wiadomości, że INSERT INTO JakasTabela (JakiesPola) SELECT JakiesPola FROM JakasTabela ORDER BY PolaSortowania nie zapewnia, że dane w tabeli docelowej sortowane według autoid będą mieć ten sam porządek, jak sortowanie zdefiniowane w poleceniu przepisującym.

0

Właśnie taki opis powinien się znaleźć w pierwszym poście :) Takie rozwiązanie da się zaimplementować, choć wydaje mi się zbędne ze względu na podane wcześniej argumenty.

Tylko teraz zamiast pola autonumerowanego tworzysz kolumnę na zwykłego INTa (albo BIGINTa), tworzysz SEQUENCE która będzie trzymać aktualny numer inkrementowany +1. Później korzystając z funkcji okna OVER używasz INSERT ... SELECT . Według dokumentacji jest to dopuszczalne, ale nie sprawdzałem.

The OVER clause is allowed with the NEXT VALUE FOR function when used in a SELECT statement or INSERT … SELECT … statement. The NEXT VALUE FOR function is not allowed in UPDATE or MERGE statements.

Więcej przeczytasz tutaj: http://msdn.microsoft.com/en-us/library/ff878370.aspx w akapicie Using a Sequence Object with an OVER ORDER BY Clause

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