Saya perlu memigrasi database SQL Server 2017 lokal ke database Azure SQL, dan saya menghadapi beberapa tantangan karena ada sedikit batasan yang harus dilalui.
Secara khusus, karena database Azure SQL hanya berfungsi dalam waktu UTC (tanpa zona waktu) dan kami membutuhkan waktu lokal, kami harus mengubah penggunaan di GETDATE()
mana - mana dalam database, yang telah terbukti lebih berfungsi daripada yang saya perkirakan.
Saya membuat fungsi yang ditentukan pengguna untuk mendapatkan waktu lokal yang berfungsi dengan benar untuk zona waktu saya:
CREATE FUNCTION [dbo].[getlocaldate]()
RETURNS datetime
AS
BEGIN
DECLARE @D datetimeoffset;
SET @D = CONVERT(datetimeoffset, SYSDATETIMEOFFSET()) AT TIME ZONE 'Pacific SA Standard Time';
RETURN(CONVERT(datetime,@D));
END
Masalah yang saya alami masalah adalah untuk benar-benar berubah GETDATE()
dengan fungsi ini di setiap tampilan, prosedur tersimpan, kolom yang dihitung, nilai default, kendala lain, dll.
Apa cara terbaik untuk menerapkan perubahan ini?
Kami berada di pratinjau publik dari Managed Instances . Masalahnya masih sama GETDATE()
, jadi tidak membantu dengan masalah ini. Pindah ke Azure adalah persyaratan. Basis data ini digunakan (dan akan digunakan) selalu di zona waktu ini.
Saya akan bekerja sebaliknya. Konversikan semua cap waktu Anda di basis data menjadi UTC, dan cukup gunakan UTC dan ikuti arus. Jika Anda memerlukan cap waktu di tz berbeda, Anda dapat membuat kolom yang dibuat menggunakan
AT TIME ZONE
(seperti yang Anda lakukan di atas) yang merender cap waktu di TZ yang ditentukan (untuk aplikasi). Tetapi, saya akan dengan serius mempertimbangkan untuk mengembalikan UTC ke aplikasi, dan menulis logika itu - logika tampilan - di aplikasi.sumber
Daripada mengekspor, mengedit secara manual, dan menjalankannya kembali, Anda dapat mencoba melakukan pekerjaan secara langsung dalam database dengan sesuatu seperti:
tentu saja memperluasnya untuk menangani fungsi, pemicu, dan sebagainya juga.
Ada beberapa peringatan:
Anda mungkin perlu sedikit lebih terang dan berurusan dengan ruang putih berbeda / ekstra antara
CREATE
danPROCEDURE
/VIEW
/<other>
. DaripadaREPLACE
untuk itu Anda mungkin lebih suka meninggalkanCREATE
di tempat dan mengeksekusi yangDROP
pertama, tetapi ini berisiko meninggalkansys.depends
dan teman-teman dari kilter manaALTER
mungkin tidak, juga jikaALTER
gagal Anda setidaknya memiliki objek yang ada masih di tempat di mana denganDROP
+CREATE
Anda dapat tidak.Jika kode Anda memiliki bau "pintar" seperti memodifikasi skema sendiri dengan TSQL ad-hoc maka Anda harus memastikan bahwa pencarian dan penggantian untuk
CREATE
->ALTER
tidak mengganggu itu.Anda akan ingin menguji kembali seluruh aplikasi setelah operasi, apakah Anda menggunakan kursor atau metode ekspor + edit + jalankan.
Saya telah menggunakan metode ini untuk membuat pembaruan skema serupa di masa lalu. Ini adalah sedikit hack, dan terasa sangat jelek, tetapi kadang-kadang itu adalah cara termudah / tercepat.
Default dan kendala lainnya dapat dimodifikasi dengan cara yang sama, meskipun itu hanya dapat dijatuhkan dan dibuat ulang alih-alih diubah. Sesuatu seperti:
Beberapa lebih menyenangkan yang mungkin perlu Anda pertahankan: jika Anda mempartisi berdasarkan waktu maka bagian-bagian itu mungkin perlu diubah juga. Sementara mempartisi waktu lebih rinci daripada hari jarang, Anda bisa memiliki masalah di mana
DATETIME
s ditafsirkan oleh fungsi pemartisian sebagai hari sebelumnya atau berikutnya tergantung pada zona waktu, membuat partisi Anda tidak selaras dengan kueri yang biasa Anda lakukan.sumber
sys
skema dan dimodifikasi secara program.CREATE OR ALTER PROCEDURE
membantu sekitar beberapa masalah pembuatan kode; masih mungkin ada masalah karena definisi yang disimpan akan membacaCREATE PROCEDURE
(tiga! spasi) dan ini tidak cocok denganCREATE PROCEDURE
atauCREATE OR ALTER PROCEDURE
.... ._.CREATE
yang tidak ada di dalam komentar dan menggantikannya. Saya tidak pernah melakukan ini / mirip di masa lalu tetapi tidak memiliki kode fungsi sekarang untuk memposting. Atau jika Anda dapat menjamin tidak ada definisi objek Anda memiliki komentar sebelumnyaCREATE
, abaikan masalah komentar dan temukan dan ganti instance pertamaCREATE
.Saya benar-benar menyukai jawaban David dan menyatakannya sebagai cara terprogram untuk melakukan sesuatu.
Tetapi Anda dapat mencoba ini hari ini untuk uji coba di Azure melalui SSMS:
Klik kanan database Anda -> Tugas -> Hasilkan Script ..
[Back Story] kami memiliki DBA junior yang memutakhirkan semua lingkungan pengujian kami ke SQL 2008 R2 sementara lingkungan produksi kami berada di SQL 2008. Ini adalah perubahan yang membuat saya merasa ngeri hingga hari ini. Untuk bermigrasi ke produksi, dari pengujian, kami harus membuat skrip dalam SQL, menggunakan skrip menghasilkan, dan dalam opsi lanjutan kami menggunakan opsi 'Jenis Data ke skrip: Skema dan Data' untuk menghasilkan file teks besar. Kami berhasil memindahkan pangkalan data uji R2 kami ke server SQL 2008 lawas kami - tempat pemulihan basis data ke versi yang lebih rendah tidak akan berfungsi. Kami menggunakan sqlcmd untuk memasukkan file besar - karena file sering kali terlalu besar untuk buffer teks SSMS.
Apa yang saya katakan di sini adalah bahwa opsi ini mungkin akan bekerja untuk Anda juga. Anda hanya perlu melakukan satu langkah tambahan dan mencari serta mengganti getdate () dengan [dbo] .getlocaldate dalam file teks yang dihasilkan. (Saya akan menempatkan fungsi Anda ke dalam database sebelum migrasi sekalipun).
(Saya tidak pernah ingin menjadi mahir dalam bantuan band pemulihan database ini, tetapi untuk sementara itu menjadi cara defacto dalam melakukan sesuatu. Dan, itu bekerja setiap saat.)
Jika Anda memilih rute ini, pastikan dan pilih tombol Advanced dan pilih semua opsi yang Anda butuhkan (baca masing-masing) untuk berpindah dari database lama ke database baru - seperti default yang Anda sebutkan. Tetapi berikan beberapa tes berjalan di Azure. Saya yakin Anda akan menemukan bahwa ini adalah salah satu solusi yang berfungsi - dengan sedikit upaya.
sumber
Pemberitahuan dikomentari sysobjects Ketik kondisi kolom. Skrip saya hanya akan mengubah proc dan UDF.
Script ini akan mengubah semua
Default Constraint
yang mengandungGetDate()
sumber
Saya telah memutakhirkan jawaban Evan Carrolls, karena saya pikir ini adalah solusi terbaik . Saya belum dapat meyakinkan kolega saya bahwa mereka harus mengubah banyak kode C #, jadi saya harus menggunakan kode yang ditulis David Spillett. Saya telah memperbaiki beberapa masalah dengan UDF, Dynamic SQL, dan Schemas (tidak semua kode menggunakan "dbo.") Seperti ini:
dan batasan default seperti ini:
UDF
Saran untuk menggunakan UDF yang mengembalikan tanggal dan waktu todays terlihat bagus, tapi saya pikir masih ada masalah kinerja yang cukup dengan UDF, jadi saya memilih untuk menggunakan solusi ZONA WAKTU yang sangat panjang dan jelek.
sumber