কোডের দ্বারা এটি উপস্থিত না থাকলে নতুন ফাংশন তৈরি করুন


15

আমি আমার ডাটাবেসে স্ক্রিপ্ট দ্বারা নতুন ফাংশন তৈরি করতে চাই। স্ক্রিপ্ট কোডটি নীচে রয়েছে:

IF Exists(Select * From sys.sysobjects A Where A.name =N'fn_myfunc' and xtype=N'FN') return;

CREATE FUNCTION fn_myfunc ()
returns varchar(10)
AS Begin
...
End

কিন্তু যখন আমি উপরের স্ক্রিপ্টটি কার্যকর করি তখন এসকিউএল সার্ভার একটি ত্রুটি প্রদান করে:

'CREATE FUNCTION' must be the first statement in a query batch.

উত্তর:


16

জানুয়ারী 2017 আপডেট করুন - এসকিউএল সার্ভার 2016+ / অ্যাজুরি এসকিউএল ডেটাবেস

এসকিউএল সার্ভার 2016 এবং অ্যাজুরে এসকিউএল ডেটাবেস-এর বর্তমান সংস্করণে এখন ফাংশন, পদ্ধতি, টেবিল, ডাটাবেস ইত্যাদির জন্য নিম্নলিখিত বাক্য গঠন রয়েছে ( DROP IF EXISTS):

DROP FUNCTION IF EXISTS dbo.fn_myfunc;

এবং এসকিউএল সার্ভার 2016 সার্ভিস প্যাক 1 মডিউলগুলির জন্য আরও কার্যকর কার্যকারিতা যুক্ত করেছে (ফাংশন, পদ্ধতি, ট্রিগার, ভিউ) যার অর্থ অনুমতি বা নির্ভরতা হারাবে না ( CREATE OR ALTER):

CREATE OR ALTER FUNCTION dbo.fn_myfunc ...

এই উভয় সিনট্যাক্স বর্ধনের ফলে উত্স নিয়ন্ত্রণ, স্থাপনা ইত্যাদির জন্য ব্যবহৃত অনেকগুলি সহজ স্ক্রিপ্ট হতে পারে can

আপনি যদি ব্যবহার করেন তবে ...


পুরানো সংস্করণ

আপনি যখন ম্যানেজমেন্ট স্টুডিও থেকে এটি স্ক্রিপ্ট করেন তখন আপনাকে এসকিউএল সার্ভার কী করতে হবে:

IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE type = 'FN' AND name = 'fn_myfunc')
BEGIN
    DECLARE @sql NVARCHAR(MAX);
    SET @sql = N'CREATE FUNCTION ...';
    EXEC sp_executesql @sql;
END

অথবা আপনি বলতে পারেন:

BEGIN TRY
    DROP FUNCTION dbo.fn_myfunc;
END TRY
BEGIN CATCH
    PRINT 'Function did not exist.';
END CATCH
GO
CREATE FUNCTION...

অথবা আপনি কেবল বলতে পারেন:

DROP FUNCTION dbo.fn_myfunc;
GO
CREATE FUNCTION...

(ফাংশনটি ইতিমধ্যে বিদ্যমান না থাকলে এখানে আপনি একটি ত্রুটি বার্তা পাবেন, তবে স্ক্রিপ্টটি পরবর্তী জিও থেকে চালিয়ে যাবে, সুতরাং ড্রপটি কাজ করেছে বা না, ফাংশনটি এখনও তৈরি হবে (পুনরায়))

মনে রাখবেন যে আপনি যদি ফাংশনটি ফেলে দেন এবং এটি পুনরায় তৈরি করেন তবে আপনি অনুমতি এবং সম্ভাব্য নির্ভরতার তথ্যও হারাবেন।


1
সুতরাং কোনও কীওয়ার্ড নেই $$ তৈরি বা প্রতিস্থাপন $$? কৃপা.
zinking

@ জিংকিং না, তবে ভবিষ্যতের সংস্করণে হতে পারে। দয়া করে ভোট / মন্তব্য করুন: সংযুক্ত.মাইক্রোসফ্ট
অ্যারন বারট্র্যান্ড

1
@ অ্যারনবার্ট্র্যান্ড এটির পক্ষে ভোট দেওয়ার পক্ষে ভাল ধারণা, তবে লিঙ্কটি নষ্ট হয়েছে
নীল

হাঁ @bluish দুঃখিত, তারা আগে যখন আমি লিংক পোস্ট করা তিন বছরের মধ্যে আইটেমটি একদা মুছে এবং এখন ... চেষ্টা connect.microsoft.com/SQLServer/feedback/details/344991/... বা connect.microsoft.com/SQLServer/feedback / বিশদ / 351217 /…
অ্যারন বারট্রান্ড

এটি এখন উপলভ্য হতে পারে: ব্লগস.এমএসএনএন.মাইক্রোসফট
ব্রুনো

1

ত্রুটিটি বেশ স্ব-বর্ণনামূলক। এটি ঠিক করার কয়েকটি উপায় রয়েছে।

  1. GOসিউডো-কীওয়ার্ড এবং DROP/ CREATEঅবজেক্টটি ব্যবহার করে ম্যানেজমেন্ট স্টুডিওর বিভিন্ন ব্যাচে স্ক্রিপ্টটি আলাদা করুন । (নোট করুন যে কীওয়ার্ডটি নিজেই ম্যানেজমেন্ট স্টুডিও বিকল্পগুলিতে পরিবর্তিত হতে পারে তবে এটি ডি ফ্যাক্টো সেটিং, সুতরাং আমি এটিকে একা রেখে দেওয়ার পরামর্শ দিই)।

    আপনি যখন কোনও স্ক্রিপ্ট রান করেন (বা কোনও স্ক্রিপ্টের নির্বাচিত অংশ), ম্যানেজমেন্ট স্টুডিও স্ক্রিপ্টের প্রতিটি অংশকে GOs এর মধ্যে পৃথক করে এবং ধারাবাহিকভাবে অংশগুলি এসকিউএল সার্ভারে পৃথক ব্যাচ হিসাবে প্রেরণ করে।

  2. অন্য ব্যাচের মধ্যে থেকে আলাদা ব্যাচ প্রেরণে গতিশীল এসকিউএল ব্যবহার করুন।

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

    অন্য উত্তরে উল্লিখিত হিসাবে, আপনি CREATEএই পদ্ধতিটি ব্যবহার করে (অথবা DROP/ অথবা এর সাথে অন্য কোনও সংমিশ্রণ CREATE) পরীক্ষা করতে পারেন / করতে পারেন । আমি যা করতে পছন্দ করি তা হ'ল স্টাব অবজেক্ট তৈরি করা যদি বস্তুর অস্তিত্ব না থাকে এবং তারপরে ALTER <object>প্রকৃতপক্ষে সৃষ্টি বা পরিবর্তন করতে ব্যবহার করুন । এই পদ্ধতির নির্ভরতাগুলি যেমন অনুমতি বা বর্ধিত বৈশিষ্ট্যগুলি হ্রাস করে না এবং একক বিবৃতিতে CREATE/ করার জন্য ত্রুটি-প্রবণ যুক্তির অনুলিপি / কপি করা প্রয়োজন হয় না ALTER

    স্কেলার ফাংশন তৈরি বা পরিবর্তনের জন্য আমি যে টেম্পলেটটি ব্যবহার করি তা এখানে। আমি এটি পাঠকের জন্য অন্যান্য ধরণের অবজেক্টগুলিতে (সঞ্চিত প্রক্স, ট্রিগার ইত্যাদি) খাপ খাইয়ে নিতে অনুশীলন হিসাবে রেখে দেব।

IF NOT EXISTS(SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[<schema>].[<function name>]') AND type IN ('FN', 'FS'))
    EXEC sp_executesql N'CREATE FUNCTION [<schema name>].[<function name>] (@a int) RETURNS int AS BEGIN /* Stub */ RETURN @a END'

EXEC sp_executesql N'
ALTER FUNCTION [<schema name>].[<function name>]
/* ... */
'

বিকল্প 1 এখানে কীভাবে কাজ করতে পারে? GOআসলে যোগ করার ফলে স্ক্রিপ্টটি ভেঙে যাওয়ার বিষয়টি নিশ্চিত হয়, যেহেতু IFউইশ কোথাও নেই।
অ্যারন বারট্র্যান্ড

@ অ্যারন: আমি সম্পাদিত DROP/ CREATEদৃশ্যের কথা ভাবছিলাম । ধন্যবাদ।
জন সেগেল

1

আপনার কাছে অবজেক্টটি বিদ্যমান রয়েছে কিনা তা যাচাইয়ের বিকল্প রয়েছে এবং databaseনা থাকলে তৈরি করুন:

IF OBJECT_ID('new_function', 'FN') IS NULL
BEGIN
  EXEC('CREATE FUNCTION new_function() RETURNS INT AS BEGIN RETURN 1 END');
END;
go

ALTER FUNCTION new_function() RETURNS INT AS
BEGIN

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