มีวิธีใดที่จะบังคับให้มีการแก้ไขชื่อรอการตัดบัญชีแม้ว่าตารางจะมีอยู่เมื่อสร้างกระบวนงานที่เก็บไว้?


10

เมื่อสร้างโพรซีเดอร์ที่เก็บไว้ใน SQL Server คุณจะได้รับอนุญาตให้อ้างถึงตารางที่ไม่มีอยู่ แต่ถ้าตารางนั้นมีอยู่คอลัมน์ใด ๆ ที่คุณอ้างถึงในขั้นตอนต้องมีอยู่ในตารางนั้น ( การแก้ปัญหาชื่อที่เลื่อนออกไป )

เป็นไปได้หรือไม่ที่จะสั่งให้ SQL Server เลื่อนการจำแนกชื่อของตารางทั้งหมดที่อ้างอิงในกระบวนการโดยไม่คำนึงว่ามีอยู่จริงหรือไม่? ฉันต้องการเก็บการตรวจสอบไวยากรณ์ทั่วไปดังนั้นแม้ว่าจะเป็นไปได้แฮ็คการนิยามโพรซีเดอร์ที่เก็บไว้ในตารางระบบไม่ใช่ตัวเลือก

ฉันคาดหวังว่าการขอทำสิ่งนี้อาจจะดูแปลก ๆดังนั้นนี่คือพื้นหลัง: ฉันสร้างคำจำกัดความของตารางโดยอัตโนมัติและขั้นตอนการจัดเก็บจากแอปพลิเคชันที่เขียนใน C # และมันยากมากสำหรับฉันที่จะเปลี่ยนรหัส พวกเขา รหัสของฉัน "รับประกัน" ว่าสคีมานั้นสอดคล้องกันในการทำธุรกรรม แต่ในปัจจุบันฉันไม่สามารถรับประกันได้ว่าจะมีการกำหนดคอลัมน์ตารางก่อนที่ฉันจะกำหนดขั้นตอนการจัดเก็บซึ่งอ้างอิงพวกเขา

ด้านล่างเป็นตัวอย่างที่ยอมรับได้ของ SQL ที่สร้างขึ้นโดย C # ซึ่ง "อธิบาย" ปัญหาที่ฉันพยายามแก้ไข

--Say this table already exists.
CREATE TABLE myTable
(
    a NVARCHAR(MAX)
)
GO

--My C# code creates something like this
BEGIN TRAN 
GO

--the stored procedure gets generated first.
CREATE PROCEDURE mySproc
AS
BEGIN
    SELECT a,b FROM myTable
END

--then the table update
ALTER TABLE myTable
    ADD b nvarchar(MAX)

COMMIT TRAN 

มันเป็นไปได้สำหรับผมที่จะแก้ไขปัญหานี้ในรหัส C # แต่ฉันหวังว่าการที่เรียบง่าย "มายากล" ปรับแต่งผมสามารถดึงในการ SQL นี้จะประหยัดเวลาได้มากสำหรับฉัน


1
คุณไม่สามารถประมวลผลการเปลี่ยนแปลงสคีมาทั้งหมดก่อนที่จะสร้าง / แก้ไขขั้นตอนใด ๆ ได้หรือไม่ ทำไมต้องมีขั้นตอนก่อนตารางถูกต้อง?
Aaron Bertrand

ตอนนี้ฉันกำลังทำตัวเลือกให้เป็นรหัส วิธีการสร้าง SQL นั้นค่อนข้างซับซ้อน (นั่นเป็นตัวอย่างง่ายๆ) แต่ดูเหมือนว่ามันจะไม่เป็น PITA เท่าที่ฉันคิด
Daniel James Bryars

2
คุณสามารถหลีกเลี่ยงได้โดยการบรรจุขั้นตอนการจัดเก็บที่เต็มไปด้วย SQL แบบไดนามิก - แต่ฉันไม่สามารถจินตนาการการสร้างสคริปต์ของคุณเพื่อจัดการกับการเปลี่ยนแปลงสคีมาแล้วขั้นตอนการจัดเก็บจะยากมาก มีตัวเลือกไม่มากนักที่บอกว่าการแก้ไขชื่อที่เลื่อนออกไปทำงานอย่างไร ข้อเสนอเพียงข้อเดียวสำหรับหนังสือที่ฉันรู้หรืออย่างน้อยที่สุดฉันสามารถอนุมานได้ว่าพวกเขาสนใจในความบันเทิงเป็นอีกวิธีหนึ่ง - ทำให้เข้มงวดมากขึ้น - ดูsommarskog.se/strict_checks.html )
Aaron Bertrand

ความคิดที่ดีเกี่ยวกับ SQL แบบไดนามิก ฉันมีปัญหาเดียวกันสำหรับทริกเกอร์ดัชนีมุมมอง Sprocs และฟังก์ชั่น แต่ฉันได้เปลี่ยนรหัสเพื่อที่จะทำการเปลี่ยนแปลงกับ Tables จากนั้นสร้างดัชนีจากนั้นเรียกใช้จากนั้นจึงทำหน้าที่จากนั้นจึง sprocs
Daniel James Bryars

ฉันชอบคำแนะนำของ sommarskog แน่นอนจะช่วยหลีกเลี่ยงข้อบกพร่อง หากพวกเขาใช้ตัวเลือกที่เข้มงวดแล้วพวกเขายังสามารถประเมิน sprocs "Strict ON" ทั้งหมดเมื่อมีการเปลี่ยนแปลงตารางเพื่อดูว่ามันแบ่ง sprocs ที่มีอยู่ - แน่นอนคุณจะต้องมี "ตรรกะการทำธุรกรรมใน DDL" ดังนั้นคุณ จากนั้นสามารถเปลี่ยนตารางและ Sprocs เป็นหนึ่งหน่วย
Daniel James Bryars

คำตอบ:


6

เลขที่

ฉันรู้สึกผิดจริง ๆ แค่พิมพ์สิ่งนั้น แต่ไม่เศร้า นั่นเป็นครั้งแรกที่ฉันได้ยินกรณีการใช้งานนี้และมันสมเหตุสมผลดี ที่ดีที่สุดในการส่งคำขอในhttp://connect.microsoft.comและลูกหลานของคุณจะสามารถทำได้ ;-)


5

ในกรณีที่คุณยังสนใจมีวิธีแก้ไขที่เป็นไปได้ที่คุณสามารถจ้างได้ นี่คือรหัสที่ได้รับการปรับปรุงซึ่งจะแนะนำ#deferResolutionตารางชั่วคราวให้กับแต่ละแบบสอบถามในกระบวนการ myTableเพราะตารางชั่วคราวจะมีอยู่เฉพาะที่รันไทม์ขั้นตอนจะสามารถรวบรวมแม้ว่าคอลัมน์ที่เหมาะสมยังไม่อยู่ใน

คุณจะได้รับแผนการดำเนินการเดียวกัน (ไม่มีการอ้างอิงถึง#deferResolutionตาราง) สำหรับแต่ละคำสั่งในกระบวนการเนื่องจากวิธีการที่เครื่องมือเพิ่มประสิทธิภาพการสืบค้นสามารถพิสูจน์ได้ว่าสิ่งนี้WHERE NOT EXISTSจะประเมินว่าเป็นจริงเสมอ

ทั้งหมดที่กล่าวมานี้เป็นแฮ็คที่น่ากลัวส่วนใหญ่ที่นำเสนอเพื่อผลประโยชน์ทางปัญญาและอาจมีกรณีที่มันหยุดลง ดังที่แอรอนกล่าวถึงคุณน่าจะดีกว่าที่จะเปลี่ยนแปลงสคีมาทั้งหมดตามลำดับที่เหมาะสม

--Say this table already exists.
CREATE TABLE myTable
(
    a NVARCHAR(MAX)
)
GO

--My C# code creates something like this
BEGIN TRAN 
GO

--the sproc gets generated first.
CREATE PROCEDURE mySproc
AS
BEGIN
    CREATE TABLE #deferResolution (dummy INT NOT NULL)
    SELECT a,b FROM myTable WHERE NOT EXISTS (SELECT * FROM #deferResolution WHERE 0=1)
END

--then the table update
ALTER TABLE myTable
    ADD b nvarchar(MAX)

COMMIT TRAN 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.