La mia vera query di lavoro era un join interno, ma questo semplice esempio con cross join sembra quasi sempre riprodurre il problema.
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT NEWID() TEST_ID
) BB ( B )
Con il mio join interno ho avuto molte righe per le quali ho aggiunto a ciascuno un GUID utilizzando la funzione NEWID () e per circa 9 su 10 di tali righe la moltiplicazione con la tabella virtuale a 2 righe ha prodotto i risultati previsti, solo 2 copie di lo stesso GUID, mentre 1 su 10 produrrebbe risultati diversi. Questo è stato inaspettato a dir poco e mi ha fatto davvero fatica a trovare questo bug nel mio script di generazione dei dati di test.
Se dai un'occhiata alle seguenti query usando anche le funzioni getdate e sysdatetime non deterministiche, non lo vedrai, non lo vedo comunque, vedo sempre lo stesso valore datetime in entrambe le righe del risultato finale.
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT GETDATE() TEST_ID
) BB ( B )
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT SYSDATETIME() TEST_ID
) BB ( B )
Attualmente sto usando SQL Server 2008 e il mio lavoro per ora è caricare le mie righe con GUID in una variabile di tabella prima di completare il mio script di generazione casuale dei dati. Una volta che li ho come valori in una tabella rispetto alla tabella virtuale, il problema scompare.
Ho una soluzione alternativa, ma sto cercando i modi per risolvere il problema senza tabelle effettive o variabili di tabella.
Durante la scrittura di questo ho provato senza successo queste possibilità: 1) posizionando newid () in una tabella virtuale nidificata:
SELECT *
FROM (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
CROSS JOIN (
SELECT TEST_ID
FROM (
SELECT NEWID() TEST_ID
) TT
) BB ( B )
2) racchiudere il newid () all'interno di un'espressione cast come:
SELECT CAST(NEWID() AS VARCHAR(100)) TEST_ID
3) invertire l'ordine di aspetto delle tabelle virtuali all'interno dell'espressione di join
SELECT *
FROM (
SELECT NEWID() TEST_ID
) BB ( B )
CROSS JOIN (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
4) utilizzando la croce non correlata si applicano
SELECT *
FROM (
SELECT NEWID() TEST_ID
) BB ( B )
CROSS APPLY (
SELECT 1 UNION ALL
SELECT 2
) AA ( A )
Poco prima di pubblicare finalmente questa domanda, ora ho provato a farlo con successo, a quanto pare, si applica una croce correlata:
SELECT *
FROM (
SELECT NEWID() TEST_ID
) BB ( B )
CROSS APPLY (
SELECT A
FROM (
SELECT 1 UNION ALL
SELECT 2
) TT ( A )
WHERE BB.B IS NOT NULL
) AA ( A )
Qualcuno ha qualche altra soluzione più elegante, più semplice? In realtà non voglio usare l'applicazione incrociata o la correlazione per una semplice moltiplicazione di righe se non devo.