আমি কি কোনও স্ক্রিপ্ট বা সঞ্চিত পদ্ধতিতে একটি এককালীন-ব্যবহার ফাংশন তৈরি করতে পারি?


109

এসকিউএল সার্ভার ২০০৫-এ কি কোনও এস -কিউএল স্ক্রিপ্ট বা সঞ্চিত কার্যবিধির ভিতরে ঘোষিত এককালীন-ব্যবহারের, বা স্থানীয় ফাংশনটির ধারণা রয়েছে? আমি যে স্ক্রিপ্টটি লিখছি তাতে কিছু জটিলতা বিমূ .় করতে চাই, তবে এটির জন্য কোনও ক্রিয়াকলাপ ঘোষণা করতে সক্ষম হওয়া প্রয়োজন।

উৎসুক.


কোনও কাজ ছাড়া আপনি যা চান তা করার সম্ভবত আরও ভাল উপায় আছে। আপনি যে কোডটি কোনও ফাংশনে রূপান্তর করতে চান তা সম্ভবত আপনার একটি স্নিপেট পোস্ট করা উচিত?
ডিফোক 42

আপনি কি গতিশীল কোনও ফাংশন তৈরি করছেন তাই প্রতিবারের চেয়ে আলাদা হয়? আপনি যদি ফাংশন সবসময় একই হন কেবল এটি ডাটাবেসে রেখে দিন
কেএম।

1
আমি কোয়েরিকে আরও পড়তে পারা যায় সে হিসাবে এটি করার চেষ্টা করছিলাম। বিশাল প্রশ্ন তৈরি করার ধারণাটি বজায় রাখা কঠিন করে তোলে।
জেপি_

উত্তর:


65

আপনি CREATE Functionআপনার স্ক্রিপ্টের শুরু এবং শেষের দিকে কল করতে পারেন DROP Function


6
আমি এই পরামর্শ দিতে যাচ্ছি। আপনার স্ক্রিপ্টটি সমাপ্ত হয় যাতে কেবল সতর্ক হন; যদি এটি বাতিল হয়ে যায়, আপনার তখনও ডিবিতে ফাংশন থাকবে।
চোকোজোশ

6
আপনি প্রতিটি রান করার আগে একটি অস্তিত্বের চেক করতে পারেন এবং যদি কিছু পাওয়া যায় তবে মুছুন।
অ্যাড্রিয়ান গডং

7
@ চোকোজোশ, যদি আপনি এটি কোনও লেনদেনে জড়ান তবে তা ঠিক হওয়া উচিত। লেনদেন বোমা হলে ফাংশনটি ডাটাবেসে থাকা উচিত নয়।
জেফ লাফে 21

12
@ জোয়েলকোহর্ন: এটি এখনও লেখার অধিকারের প্রয়োজন হয় না।
ব্যবহারকারী 2284570

2
মনে রাখবেন যে এটি কোনও ফাংশনের অভ্যন্তরে কাজ করবে না - ফাংশনের অভ্যন্তরে অস্থায়ী ফাংশন অনুমোদিত নয়। দেখুন: টেকনিকট.মাইক্রোসফট.ইন- ইউএস
ড্যানিয়েল নীল

95

আপনি এইভাবে অস্থায়ী সঞ্চিত পদ্ধতি তৈরি করতে পারেন:

create procedure #mytemp as
begin
   select getdate() into #mytemptable;
end

একটি এসকিউএল স্ক্রিপ্টে, তবে কার্যকরী নয়। আপনার প্রোপ স্টোরটি এটির ফলস্বরূপ একটি টেম্প টেবিলের মধ্যে থাকতে পারে, তবে সেই তথ্যটি স্ক্রিপ্টে পরে ব্যবহার করুন ..


7
এই উত্তর হওয়া উচিত। এটি যদি কেবল সংযোগটি অস্থায়ী (একক #) কে স্কোপ করে থাকে তবে সত্যই এটি একক-ব্যবহারযোগ্য, এবং স্কেল ব্যবহারকারীদের বিধিনিষেধকে সরিয়ে দেওয়ার সুবিধা অর্জন করে।
টড

তখন কীভাবে এটি ব্যবহার করা হয়? নির্বাচন পদ্ধতিতে প্রকাশের ক্ষেত্রে এটি কী টাইপো নয়?
jgomo3

আমি BEGINকীওয়ার্ডটি সরিয়ে ফেললে আমি আপনার উদাহরণ সঞ্চিত প্রক্রিয়া থেকে ফলাফল পেতে সক্ষম হয়েছি এবং এর ENDসাথে কীওয়ার্ডটি প্রতিস্থাপন করব GO
জোসেফ ডাইকস্ট্রা

ওপি একটি অস্থায়ী ফাংশন চেয়েছিল এবং কমপক্ষে এসকিউএল সার্ভার 2012 ফাংশনের জন্য #-সায়েন্টেক্সের অনুমতি দেবে না। শুধুমাত্র পদ্ধতি।
এর্ক

এটি কোনও স্ক্রিপ্টের মধ্যে কাজ করে না এবং এখনও অনুমতিগুলির প্রয়োজন হতে পারে। পুনরাবৃত্তিক বিভাগগুলি এড়ানোর জন্য এসকিউএল-এর একমাত্র বিকল্পটি হল স্টেটমেন্টের সাথে।
alex.peter

25

সাধারণ সারণী এক্সপ্রেশন আপনাকে মূলত এমন ভিউগুলি সংজ্ঞায়িত করতে দেয় যা কেবলমাত্র আপনার নির্বাচন, সন্নিবেশ, আপডেট এবং বিবৃতি মোছার ক্ষেত্রের মধ্যে স্থায়ী হয়। আপনার যা করা দরকার তার উপর নির্ভর করে তারা মারাত্মকভাবে কার্যকর হতে পারে।


5
এটি সঠিক উত্তর হিসাবে গ্রহণ করা উচিত। গৃহীত উত্তর থ্রেড নিরাপদ নয়।
কল্যাণ

11
আপনি যা করার চেষ্টা করছেন তা নির্ভর করে। আমি এই প্রশ্নটি খুঁজে পেয়েছি কারণ আমি একটি ডেটা সিডার লিখছি এবং আমি 10 লাইন মার্জার ইন 30 বার পুনরাবৃত্তি করতে চাই না। আমি থ্রেডসেফের বিষয়ে চিন্তা করি না এবং সিটিই আমার পক্ষে কাজ করবে না।
সলিসিকেল

16
আমি মনে করি এই উত্তর, এবং এটির সঠিক উত্তর যাচাই করেছে, মিস করুন যে প্রশ্নটি একটি টেম্পল টেবিল নয়, একটি অস্থায়ী ফাংশনের সন্ধান করছে। আমি যদি কিছু মিস করছি তবে (অস্বাভাবিক নয়) সিটিই টেপ টেবিলের সাথে তুলনীয়।
জেডি লং

8
একটি ফাংশন আর্গুমেন্ট নিতে পারে যখন কোনও সিটিই না পারে।
রেজওয়ান ফ্ল্যাভিয়াস পান্ডা

4
একটি সিটিই এবং একটি টেম্প স্টোর করা পদ্ধতির মধ্যে অনেক পার্থক্য রয়েছে (যা এখানে সঠিক উত্তর আইএমও)। প্রারম্ভিকদের জন্য, সিটিই কেবলমাত্র একটি বিবৃতিতে উপস্থিত থাকে, যেখানে অস্থায়ী ভেরিয়েবলগুলি কোনও স্ক্রিপ্ট জুড়ে ব্যবহার করা যায়। অন্যান্য পার্থক্যের মধ্যে রয়েছে: (১) সিটিইরা একই যুক্তি রাখতে পারে না যে কোনও এসপি পারে, (২) সিটিই ভেরিয়েবল গ্রহণ করতে পারে না। একটি সিটিই হ'ল একটি বাক্যটিতে ব্যবহারের জন্য খুব সহজে নেস্টেড টেবিল এক্সপ্রেশন তৈরি করতে আপনাকে অনুমতি দেওয়ার জন্য একটি সিনট্যাকটিক চিনি। তারপরেও যদি আপনি সতর্কতা অবগত না হন তবে এগুলি বিপজ্জনক পারফরম্যান্স-ভিত্তিক হতে পারে।
Lopsided

12

আমি জানি গতিশীল এসকিউএল প্রস্তাব দেওয়ার জন্য আমি সমালোচিত হতে পারি তবে কখনও কখনও এটি একটি ভাল সমাধান হয়। এই বিষয়টি বিবেচনা করার আগে নিশ্চিত হয়ে নিন যে আপনি সুরক্ষা সম্পর্কিত প্রভাবগুলি বুঝতে পেরেছেন।

DECLARE @add_a_b_func nvarchar(4000) = N'SELECT @c = @a + @b;';
DECLARE @add_a_b_parm nvarchar(500) = N'@a int, @b int, @c int OUTPUT';

DECLARE @result int;
EXEC sp_executesql @add_a_b_func, @add_a_b_parm, 2, 3, @c = @result OUTPUT;
PRINT CONVERT(varchar, @result); -- prints '5'

4

স্ক্রিপ্টগুলিতে আপনার কাছে আরও বিকল্প রয়েছে এবং যুক্তিসঙ্গত পচে যাওয়াতে আরও ভাল শট। এসকিউএলসিএমডি মোডে অনুসন্ধান করুন (ক্যোয়ারী মেনু -> এসকিউএলসিএমডি মোড), বিশেষত: সেটভার এবং: আরআরড।

সঞ্চিত পদ্ধতির মধ্যে আপনার বিকল্পগুলি খুব সীমিত। আপনি কোনও পদ্ধতির বডি দিয়ে সরাসরি কোনও ফাংশন সংজ্ঞায়িত করতে পারবেন না। ডায়নামিক এসকিউএল সহ আপনি যা করতে পারেন তা হ'ল:

create proc DoStuff
as begin

  declare @sql nvarchar(max)

  /*
  define function here, within a string
  note the underscore prefix, a good convention for user-defined temporary objects
  */
  set @sql = '
    create function dbo._object_name_twopart (@object_id int)
    returns nvarchar(517) as
    begin
      return 
        quotename(object_schema_name(@object_id))+N''.''+
        quotename(object_name(@object_id))
    end
  '

  /*
  create the function by executing the string, with a conditional object drop upfront
  */
  if object_id('dbo._object_name_twopart') is not null drop function _object_name_twopart
  exec (@sql)

  /*
  use the function in a query
  */
  select object_id, dbo._object_name_twopart(object_id) 
  from sys.objects
  where type = 'U'

  /*
  clean up
  */
  drop function _object_name_twopart

end
go

এটি একটি বিশ্বব্যাপী অস্থায়ী ফাংশনটির সান্নিধ্য করে, যদি এরকম কিছু বিদ্যমান থাকে। এটি এখনও অন্য ব্যবহারকারীদের কাছে দৃশ্যমান। নামটি অনন্য করার জন্য আপনি নিজের সংযোগের @@ এসপিআইডি যুক্ত করতে পারেন, তবে তারপরে গতিশীল এসকিউএল ব্যবহারের জন্য বাকি প্রক্রিয়াটিরও প্রয়োজন হবে।


3

এমএস এসকিউএলে স্কেলার ইউডিএফটির প্রয়োজনীয়তা অর্জনের জন্য আমি অতীতকে যা ব্যবহার করেছি তা নীচে:

IF OBJECT_ID('tempdb..##fn_Divide') IS NOT NULL DROP PROCEDURE ##fn_Divide
GO
CREATE PROCEDURE ##fn_Divide (@Numerator Real, @Denominator Real) AS
BEGIN
    SELECT Division =
        CASE WHEN @Denominator != 0 AND @Denominator is NOT NULL AND  @Numerator != 0 AND @Numerator is NOT NULL THEN
        @Numerator / @Denominator
        ELSE
            0
        END
    RETURN
END
GO

Exec ##fn_Divide 6,4

এই পদ্ধতির যা পদ্ধতির জন্য একটি বৈশ্বিক পরিবর্তনশীল ব্যবহার করে আপনাকে কেবলমাত্র আপনার স্ক্রিপ্টগুলিতেই নয়, আপনার ডায়নামিক এসকিউএল প্রয়োজনীয়তায়ও ফাংশনটি ব্যবহার করতে দেয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.