সমস্যা : sp_executesql এর প্যারামিটার হিসাবে ব্যবহারকারী সংজ্ঞায়িত টেবিল প্রকারগুলির সাথে একটি জ্ঞাত সমস্যা আছে ? উত্তর - না, আমি একজন বোকা।
স্ক্রিপ্ট সেট আপ করুন
এই স্ক্রিপ্টটি প্রতিটি টেবিল, পদ্ধতি এবং ব্যবহারকারীর সংজ্ঞায়িত সারণী প্রকারের তৈরি করে (কেবলমাত্র এসকিউএল সার্ভার 2008+ কেবলমাত্র)।
গাদাটির উদ্দেশ্য হ'ল ডেটা প্রক্রিয়াটিতে তৈরি করে এমন একটি নিরীক্ষণ সরবরাহ করা। কোনও সীমাবদ্ধতা নেই, ডেটা beingোকানো থেকে রোধ করার জন্য কিছুই নেই।
পদ্ধতিটি ব্যবহারকারীকে সংজ্ঞায়িত টেবিল ধরণের পরামিতি হিসাবে গ্রহণ করে। সমস্ত প্রকল্পগুলি টেবিলের মধ্যে .োকানো হয়।
ব্যবহারকারীর সংজ্ঞায়িত টেবিল প্রকারটিও বোগ সহজ, কেবল একটি একক কলাম
আমি নীচে নিম্নলিখিতটি চালিয়েছি 11.0.1750.32 (X64)
এবং 10.0.4064.0 (X64)
হ্যাঁ, আমি জানি যে বাক্সটি প্যাচ করা যেতে পারে, আমি এটি নিয়ন্ত্রণ করি না।
-- this table record that something happened
CREATE TABLE dbo.UDTT_holder
(
ServerName varchar(200)
, insert_time datetime default(current_timestamp)
)
GO
-- user defined table type transport mechanism
CREATE TYPE dbo.UDTT
AS TABLE
(
ServerName varchar(200)
)
GO
-- stored procedure to reproduce issue
CREATE PROCEDURE dbo.Repro
(
@MetricData dbo.UDTT READONLY
)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO dbo.UDTT_holder
(ServerName)
SELECT MD.* FROM @MetricData MD
END
GO
সমস্যা পুনরুত্পাদন
এই স্ক্রিপ্টটি সমস্যাটি দেখায় এবং এটি কার্যকর করতে পাঁচ সেকেন্ড সময় নেওয়া উচিত। আমি আমার ব্যবহারকারীর সংজ্ঞায়িত টেবিল প্রকারের দুটি উদাহরণ তৈরি করি এবং তারপরে এগুলিকে পাস করার জন্য দুটি ভিন্ন উপায় চেষ্টা করি sp_executesql
। প্রথম অনুরোধে প্যারামিটার ম্যাপিং আমি এসকিউএল প্রোফাইলার থেকে ক্যাপচার করেছি তা নকল করে। আমি তখন sp_executesql
মোড়ক ছাড়াই পদ্ধতিটি কল করি ।
SET NOCOUNT ON
DECLARE
@p3 dbo.UDTT
, @MetricData dbo.UDTT
INSERT INTO @p3 VALUES(N'SQLB\SQLB')
INSERT INTO @MetricData VALUES(N'SQLC\SQLC')
-- nothing up my sleeve
SELECT * FROM dbo.UDTT_holder
SELECT CONVERT(varchar(24), current_timestamp, 121) + ' Firing sp_executesql' AS commentary
-- This does nothing
EXECUTE sp_executesql N'dbo.Repro',N'@MetricData dbo.UDTT READONLY',@MetricData=@p3
-- makes no matter if we're mapping variables
EXECUTE sp_executesql N'dbo.Repro',N'@MetricData dbo.UDTT READONLY',@MetricData
-- Five second delay
waitfor delay '00:00:05'
SELECT CONVERT(varchar(24), current_timestamp, 121) + ' Firing proc' AS commentary
-- this does
EXECUTE dbo.Repro @p3
-- Should only see the latter timestamp
SELECT * FROM dbo.UDTT_holder
GO
ফলাফল : নীচে আমার ফলাফল। টেবিলটি প্রাথমিকভাবে খালি। আমি বর্তমান সময় নির্গত করি এবং দুটি কল করি sp_executesql
। আমি 5 সেকেন্ড অপেক্ষা করতে পারি এবং বর্তমান সময় নির্গত করতে সঞ্চিত প্রক্রিয়াটি নিজে কল করে এবং শেষ পর্যন্ত নিরীক্ষার টেবিলটি ফেলে রাখি।
আপনি যেমন টাইমস্ট্যাম্প থেকে দেখতে পাচ্ছেন, বি রেকর্ডের জন্য রেকর্ডটি স্ট্রেড স্টোরেজ পদ্ধতির অনুরোধের সাথে মিলে যায়। এছাড়াও, কোনও এসকিউএলসি রেকর্ড নেই।
ServerName insert_time
------------------------------------------------------------------------
commentary
-------------------------------------------------
2012-02-02 13:09:05.973 Firing sp_executesql
commentary
-------------------------------------------------
2012-02-02 13:09:10.983 Firing proc
ServerName insert_time
------------------------------------------------------------------------
SQLB\SQLB 2012-02-02 13:09:10.983
লিপি ছিঁড়ে ফেলুন
এই স্ক্রিপ্টটি সঠিক ক্রমে অবজেক্টগুলি সরিয়ে ফেলবে (পদ্ধতির উল্লেখটি সরানোর আগে আপনি টাইপটি ফেলে দিতে পারবেন না)
-- cleanup
DROP TABLE dbo.UDTT_holder
DROP PROCEDURE dbo.Repro
DROP TYPE dbo.UDTT
GO
কেন এটি গুরুত্বপূর্ণ
কোডটি নির্বোধ বলে মনে হচ্ছে তবে প্রো-প্রোকে একটি "সরাসরি" কল বনাম sp_execute ব্যবহারের উপর আমার খুব বেশি নিয়ন্ত্রণ নেই। কল চেইন উচ্চতর করুন, আমি ADO.NET গ্রন্থাগারটি ব্যবহার করছি এবং আমি আগের মতো একটি টিভিপিতে পাস করছি । পরামিতি ধরন সঠিকভাবে সেট করা হয় System.Data.SqlDbType.Structured এবং CommandType সেট করা হয় System.Data.CommandType.StoredProcedure ।
আমি কেন নুব (সম্পাদনা)
রব এবং মার্টিন স্মিথ যা দেখেছিলাম তা দেখেছি - sp_executesql এ দেওয়া বিবৃতিটি @MetricData
প্যারামিটারটি ব্যবহার করে নি । একটি আনপাস করা / ম্যাপ করা প্যারামিটার ব্যবহার হতে যাচ্ছে না।
আমি আমার ওয়ার্কিং সি # টেবিলের মূল্যবান-পরামিতি কোডটি পাওয়ারশেলের সাথে অনুবাদ করছিলাম এবং যেহেতু এটি সংকলিত হয়েছে, এটি কোডটি ভুল হতে পারে না ; এটা ছাড়া। এই প্রশ্নের আপ লেখার সময়, আমি উপলব্ধি আমি লাগাই নি CommandType
করার StoredProcedure
তাই আমি যে লাইন যোগ এবং কোড পুনরায় দৌড়ে কিন্তু তাই আমি অনুমান যে সমস্যা ছিল না প্রোফাইলার মধ্যে ট্রেস পরিবর্তন হয়নি।
মজার গল্প - আপনি যদি আপডেট হওয়া ফাইলটি সংরক্ষণ না করেন, এটি চালানো কোনও তাত্পর্যপূর্ণ করবে না। আমি এই সকালে পেয়েছি এবং এটি পুনরায় চালিত করেছি (সংরক্ষণের পরে) এবং ADO.NET এটি অনুবাদ করেছে EXEC dbo.Repro @MetricData=@p3
যা ঠিক কাজ করে।
dbo.Repro
এবং প্যারামিটারগুলিতে পাস করা মোটেও ব্যবহার করে না।