পদ্ধতিটি সরবরাহ করা হয়নি এমন পরামিতি প্রত্যাশা করে


106

এসকিউএল সার্ভারে একটি সঞ্চিত পদ্ধতিতে অ্যাক্সেস করার সময় আমি ত্রুটিটি পাচ্ছি

Server Error in '/' Application.
Procedure or function 'ColumnSeek' expects parameter '@template', which was not supplied. 

আমি যখন প্যারামিটারটি (System.data.SqlClient)সরবরাহ করছি তবুও আমি যখন স্ক্রিনে নেট নেট ডেটা সংযোগের মাধ্যমে প্যারামিটার সহ একটি সঞ্চিত প্রক্রিয়া কল করি তখন এটি ঘটছে । এখানে আমার কোড।

SqlConnection sqlConn = new SqlConnection(connPath);
sqlConn.Open();

//METADATA RETRIEVAL
string sqlCommString = "QCApp.dbo.ColumnSeek";
SqlCommand metaDataComm = new SqlCommand(sqlCommString, sqlConn);
metaDataComm.CommandType = CommandType.StoredProcedure;
SqlParameter sp = metaDataComm.Parameters.Add("@template",SqlDbType.VarChar,50);
sp.Value = Template;

SqlDataReader metadr = metaDataComm.ExecuteReader();

এবং আমার সঞ্চিত পদ্ধতিটি হ'ল:

   USE [QCApp]
   GO
   SET ANSI_NULLS ON
   GO
   SET QUOTED_IDENTIFIER ON
   GO

   ALTER PROCEDURE [dbo].[ColumnSeek] 
       @template varchar(50)
   AS
   EXEC('SELECT Column_Name, Data_Type 
   FROM [QCApp].[INFORMATION_SCHEMA].[COLUMNS] 
   WHERE TABLE_NAME = ' + @template);

আমি এখানে কী ভুল করছি তা বোঝার চেষ্টা করছি।

সম্পাদনা করুন: দেখা যাচ্ছে যে টেমপ্লেটটি নালাগুলি ছিল কারণ আমি ইউআরএল পেরিয়ে যাওয়া প্যারামিটারের থেকে এর মূল্য পাচ্ছিলাম এবং আমি ইউআরএল প্যারামটি পাসিংয়ে স্ক্রু করেছি (আমি এর @পরিবর্তে এবং এর পরিবর্তে ব্যবহার করছিলাম &)


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

দেখুন stackoverflow.com/a/26374810/1860652 সঞ্চিত পদ্ধতি নির্বাহ করুন এবং এই ত্রুটি পাবার জন্য
AlexFoxGill

এটি যে কোনও কারণেই আজ প্রথম পৃষ্ঠায় শেষ হয়েছে। তবে মনে হচ্ছে এটি এসকিউএল ইঞ্জেকশনের পক্ষে ঝুঁকিপূর্ণ যদি "টেম্পলেট" মান ক্লায়েন্টের ইউআরএল থেকে আসে! খুব কমপক্ষে আমি ব্যবহার করার পরামর্শ দিচ্ছিQUOTENAME(@template)
মার্ক সোউল

উত্তর:


85

আমি আমার অ্যাপ্লিকেশন কোডটি যাচাই করে দেখব যে আপনি @ স্ট্যাম্পলেটটি কী মান নির্ধারণ করছেন। আমি সন্দেহ করি এটি নাল এবং এতে সমস্যা রয়েছে lies


হ্যাঁ, টেমপ্লেটটি নাল ছিল, আমি এটি আগে সেট করতে ভুলে গিয়েছিলাম।
টনি পিটারসন

35
আমি কি কেবল যুক্ত করতে পারি যে ডিবিএনল হ'ল সি #
থ্যাবডডগ

295

এখানে অন্য উত্তরগুলি ছাড়াও, যদি আপনি রাখতে ভুলে যান:

cmd.CommandType = CommandType.StoredProcedure;

তাহলে আপনিও এই ত্রুটি পাবেন get


আপনি যদি ভিজ্যুয়াল স্টুডিও থেকে এটি ডিবাগ করছেন: প্রতিবেদনের ডেটা ট্যাবে [লেআউট এবং পূর্বরূপ ট্যাবগুলির পাশে] নির্বাচিত ডেটাसेटের নামের পাশে, অন্য একটি ড্রপ ডাউন নিয়ন্ত্রণ রয়েছে যা আপনাকে কমান্ড টাইপ পরিবর্তন করতে দেয়। উপভোগ করুন!
সর্বজন ওয়েলদেব

2
হ্যাঁ, স্ক্যালএক্সেপশন অদ্ভুত - এটি আপনাকে বলে যে এটি একটি প্রক্রিয়া হিসাবে এটি জানে তবে তারপরে আপনাকে এটি কমান্ডটাইপ সম্পত্তি সেট করে রাখতে হবে যে এটি একটি প্রক্রিয়া!
তাহির হাসান

@ তাহির, আমার মনে হয় ত্রুটিটি "পদ্ধতি "টিকে জেনেরিক শব্দ হিসাবে ব্যবহার করছে (যেমন" বা ফাংশন "যোগ করার পরামর্শ দিয়েছিল) বরং এটি সচেতন করার পরিবর্তে অভিপ্রায়টি এসকিউএল ডিবি সঞ্চিত পদ্ধতি।
ব্রায়ান

3
এখানে আসা 99% লোকের জন্য এটিই সমাধান এটি আমি কল্পনা করি
জোনেসোপলিস

দাম্মিত, সমাধানটি এত সহজ কেন ছিল। ধন্যবাদ. আমি জানতাম যে প্যারামিটারটির অস্তিত্ব ছিল এবং এটি বাতিল ছিল না এবং এটিই এটি গ্রহণ করেছিল took
জন্মগত টুডোস্টফ

27

এই সমস্যাটি সাধারণত উপরে বর্ণিত এইচএলজিইএম হিসাবে প্যারামিটারের মানটি নালায় সেট করার কারণে ঘটে থাকে । আমি ভেবেছিলাম যে আমি এই সমস্যার নতুন কিছু সমাধান সম্পর্কে বিস্তারিতভাবে জানাব যা আমি এই সমস্যায় নতুন মানুষের উপকারের জন্য দরকারী বলে মনে করেছি।

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

CREATE PROCEDURE GetEmployeeDetails
    @DateOfBirth    DATETIME = NULL,
    @Surname        VARCHAR(20),
    @GenderCode     INT = NULL,
AS

এর অর্থ হ'ল যদি প্যারামিটারটি কিছু শর্তে কোডে বাতিল হয়ে যায় তবে .NET প্যারামিটার সেট করবে না এবং সঞ্চিত পদ্ধতিটি তারপরে নির্ধারিত ডিফল্ট মানটি ব্যবহার করবে। আর একটি সমাধান, আপনি যদি কোডটিতে সমস্যাটি সত্যিই সমাধান করতে চান তবে একটি এক্সটেনশন পদ্ধতি ব্যবহার করা হবে যা আপনার জন্য সমস্যাটি পরিচালনা করে, যেমন:

public static SqlParameter AddParameter<T>(this SqlParameterCollection parameters, string parameterName, T value) where T : class
{
    return value == null ? parameters.AddWithValue(parameterName, DBNull.Value) : parameters.AddWithValue(parameterName, value);
}

ম্যাট হ্যামিল্টনের এখানে একটি ভাল পোস্ট রয়েছে যা এই অঞ্চলটি নিয়ে কাজ করার সময় আরও কয়েকটি দুর্দান্ত এক্সটেনশন পদ্ধতির তালিকা করে।


12

আমার একটি সমস্যা ছিল যেখানে আমি একটি পূর্ণসংখ্যার পরমকে 0 সরবরাহ করার সময় ত্রুটিটি পেতে পারি। এবং এটি পাওয়া গেছে:

cmd.Parameters.AddWithValue("@Status", 0);

কাজ করে, কিন্তু এটি কার্যকর করে না:

cmd.Parameters.Add(new SqlParameter("@Status", 0));

6
দ্বিতীয়টি কাজ না করার কারণ হ'ল সংকলকটি মনে করে আপনি স্কেলপ্যারামিটার কনস্ট্রাক্টরের ওভারলোড (স্ট্রিং, এসকিএলডিবিটাইপ) কল করছেন । এখানে মন্তব্য দেখুন ।
কিথ

1
আপনি যদি Addসিনট্যাক্সটি ব্যবহার করতে চান , বা আপনি আপনার কমান্ডের জন্য কোনও অবজেক্ট ইনিশিয়ালাইজার ব্যবহার করছেন, আপনি একটি নামযুক্ত প্যারামিটার ব্যবহার করতে পারেন:cmd.Parameters.Add(new SqlParameter("@Status", value: 0));
user888734

7

আমার ক্ষেত্রে, DBNULL.Valueসঞ্চিত প্রক্রিয়াগুলির পরামিতিগুলির সংজ্ঞায়িত nullনয় তবে মান হিসাবে কোড থেকে আমাকে কোড (যদি অন্য শর্ত ব্যবহার করে) পাস করতে হয়েছিল null


5

সঞ্চিত প্রক্রিয়া কল করার সময় আমি একই ধরণের সমস্যাটি দেখতে পাই

CREATE PROCEDURE UserPreference_Search
    @UserPreferencesId int,
    @SpecialOfferMails char(1),
    @NewsLetters char(1),
    @UserLoginId int,
    @Currency varchar(50)
AS
DECLARE @QueryString nvarchar(4000)

SET @QueryString = 'SELECT UserPreferencesId,SpecialOfferMails,NewsLetters,UserLoginId,Currency FROM UserPreference'
IF(@UserPreferencesId IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE UserPreferencesId = @DummyUserPreferencesId';
END

IF(@SpecialOfferMails IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE SpecialOfferMails = @DummySpecialOfferMails';
END

IF(@NewsLetters IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE NewsLetters = @DummyNewsLetters';
END

IF(@UserLoginId IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE UserLoginId = @DummyUserLoginId';
END

IF(@Currency IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE Currency = @DummyCurrency';
END

EXECUTE SP_EXECUTESQL @QueryString
                     ,N'@DummyUserPreferencesId int, @DummySpecialOfferMails char(1), @DummyNewsLetters char(1), @DummyUserLoginId int, @DummyCurrency varchar(50)'
                     ,@DummyUserPreferencesId=@UserPreferencesId
                     ,@DummySpecialOfferMails=@SpecialOfferMails
                     ,@DummyNewsLetters=@NewsLetters
                     ,@DummyUserLoginId=@UserLoginId
                     ,@DummyCurrency=@Currency;

অনুসন্ধানের জন্য কোয়েরিটি গতিশীলরূপে তৈরি করছে যার উপরে আমি একজনকে ডাকছিলাম:

public DataSet Search(int? AccessRightId, int? RoleId, int? ModuleId, char? CanAdd, char? CanEdit, char? CanDelete, DateTime? CreatedDatetime, DateTime? LastAccessDatetime, char? Deleted)
    {
        dbManager.ConnectionString = ConfigurationManager.ConnectionStrings["MSSQL"].ToString();
        DataSet ds = new DataSet();
        try
        {
            dbManager.Open();
            dbManager.CreateParameters(9);
            dbManager.AddParameters(0, "@AccessRightId", AccessRightId, ParameterDirection.Input);
            dbManager.AddParameters(1, "@RoleId", RoleId, ParameterDirection.Input);
            dbManager.AddParameters(2, "@ModuleId", ModuleId, ParameterDirection.Input);
            dbManager.AddParameters(3, "@CanAdd", CanAdd, ParameterDirection.Input);
            dbManager.AddParameters(4, "@CanEdit", CanEdit, ParameterDirection.Input);
            dbManager.AddParameters(5, "@CanDelete", CanDelete, ParameterDirection.Input);
            dbManager.AddParameters(6, "@CreatedDatetime", CreatedDatetime, ParameterDirection.Input);
            dbManager.AddParameters(7, "@LastAccessDatetime", LastAccessDatetime, ParameterDirection.Input);
            dbManager.AddParameters(8, "@Deleted", Deleted, ParameterDirection.Input);
            ds = dbManager.ExecuteDataSet(CommandType.StoredProcedure, "AccessRight_Search");
            return ds;
        }
        catch (Exception ex)
        {
        }
        finally
        {
            dbManager.Dispose();
        }
        return ds;
    }

তারপরে প্রচুর মাথার স্ক্র্যাচিংয়ের পরে আমি সঞ্চিত পদ্ধতিটি এতে পরিবর্তন করেছি:

ALTER PROCEDURE [dbo].[AccessRight_Search]
    @AccessRightId int=null,
    @RoleId int=null,
    @ModuleId int=null,
    @CanAdd char(1)=null,
    @CanEdit char(1)=null,
    @CanDelete char(1)=null,
    @CreatedDatetime datetime=null,
    @LastAccessDatetime datetime=null,
    @Deleted char(1)=null
AS
DECLARE @QueryString nvarchar(4000)
DECLARE @HasWhere bit
SET @HasWhere=0

SET @QueryString = 'SELECT a.AccessRightId, a.RoleId,a.ModuleId, a.CanAdd, a.CanEdit, a.CanDelete, a.CreatedDatetime, a.LastAccessDatetime, a.Deleted, b.RoleName, c.ModuleName FROM AccessRight a, Role b, Module c WHERE a.RoleId = b.RoleId AND a.ModuleId = c.ModuleId'

SET @HasWhere=1;

IF(@AccessRightId IS NOT NULL)
    BEGIN
        IF(@HasWhere=0) 
            BEGIN
                SET @QueryString = @QueryString + ' WHERE a.AccessRightId = @DummyAccessRightId';
                SET @HasWhere=1;
            END
        ELSE                SET @QueryString = @QueryString + ' AND a.AccessRightId = @DummyAccessRightId';
    END

IF(@RoleId IS NOT NULL)
    BEGIN
        IF(@HasWhere=0)
            BEGIN   
                SET @QueryString = @QueryString + ' WHERE a.RoleId = @DummyRoleId';
                SET @HasWhere=1;
            END
        ELSE            SET @QueryString = @QueryString + ' AND a.RoleId = @DummyRoleId';
    END

IF(@ModuleId IS NOT NULL)
BEGIN
    IF(@HasWhere=0) 
            BEGIN   
                SET @QueryString = @QueryString + ' WHERE a.ModuleId = @DummyModuleId';
                SET @HasWhere=1;
            END
    ELSE SET @QueryString = @QueryString + ' AND a.ModuleId = @DummyModuleId';
END

IF(@CanAdd IS NOT NULL)
BEGIN
    IF(@HasWhere=0) 
            BEGIN       
                SET @QueryString = @QueryString + ' WHERE a.CanAdd = @DummyCanAdd';
                SET @HasWhere=1;
            END
    ELSE SET @QueryString = @QueryString + ' AND a.CanAdd = @DummyCanAdd';
END

IF(@CanEdit IS NOT NULL)
BEGIN
    IF(@HasWhere=0) 
        BEGIN
            SET @QueryString = @QueryString + ' WHERE a.CanEdit = @DummyCanEdit';
            SET @HasWhere=1;
        END
    ELSE SET @QueryString = @QueryString + ' AND a.CanEdit = @DummyCanEdit';
END

IF(@CanDelete IS NOT NULL)
BEGIN
    IF(@HasWhere=0) 
        BEGIN
            SET @QueryString = @QueryString + ' WHERE a.CanDelete = @DummyCanDelete';
            SET @HasWhere=1;
        END
    ELSE SET @QueryString = @QueryString + ' AND a.CanDelete = @DummyCanDelete';
END

IF(@CreatedDatetime IS NOT NULL)
BEGIN
    IF(@HasWhere=0) 
    BEGIN
        SET @QueryString = @QueryString + ' WHERE a.CreatedDatetime = @DummyCreatedDatetime';
        SET @HasWhere=1;
    END
    ELSE SET @QueryString = @QueryString + ' AND a.CreatedDatetime = @DummyCreatedDatetime';
END

IF(@LastAccessDatetime IS NOT NULL)
BEGIN
    IF(@HasWhere=0) 
        BEGIN
            SET @QueryString = @QueryString + ' WHERE a.LastAccessDatetime = @DummyLastAccessDatetime';
            SET @HasWhere=1;
        END
    ELSE SET @QueryString = @QueryString + ' AND a.LastAccessDatetime = @DummyLastAccessDatetime';
END

IF(@Deleted IS NOT NULL)
BEGIN
  IF(@HasWhere=0)   
    BEGIN
        SET @QueryString = @QueryString + ' WHERE a.Deleted = @DummyDeleted';
        SET @HasWhere=1;
    END
  ELSE SET @QueryString = @QueryString + ' AND a.Deleted = @DummyDeleted';
END

PRINT @QueryString

EXECUTE SP_EXECUTESQL @QueryString
                      ,N'@DummyAccessRightId int, @DummyRoleId int, @DummyModuleId int, @DummyCanAdd char(1), @DummyCanEdit char(1), @DummyCanDelete char(1), @DummyCreatedDatetime datetime, @DummyLastAccessDatetime datetime, @DummyDeleted char(1)'
                      ,@DummyAccessRightId=@AccessRightId
                      ,@DummyRoleId=@RoleId
                      ,@DummyModuleId=@ModuleId
                      ,@DummyCanAdd=@CanAdd
                      ,@DummyCanEdit=@CanEdit
                      ,@DummyCanDelete=@CanDelete
                      ,@DummyCreatedDatetime=@CreatedDatetime
                      ,@DummyLastAccessDatetime=@LastAccessDatetime
                      ,@DummyDeleted=@Deleted;

আমি এখানে অনুসরণযোগ্যভাবে বাতিল হয়ে যাওয়ার জন্য সঞ্চিত প্রক্রিয়াটির ইনপুট প্যারামগুলি শুরু করছি

    @AccessRightId int=null,
@RoleId int=null,
@ModuleId int=null,
@CanAdd char(1)=null,
@CanEdit char(1)=null,
@CanDelete char(1)=null,
@CreatedDatetime datetime=null,
@LastAccessDatetime datetime=null,
@Deleted char(1)=null

এটা আমার জন্য কৌশল করেছে।

আমি আশা করি একইরকম ফাঁদে পড়ে এমন কারও পক্ষে এটি সহায়ক হবে।


3

যদি টেমপ্লেট সেট না করা থাকে (যেমন == নাল) তবে এই ত্রুটিটিও উত্থাপিত হবে।

আরও মন্তব্য:

আপনি যদি প্যারামিটার যুক্ত করার সময়গুলির মধ্যে প্যারামিটারের মানটি জানেন তবে আপনি অ্যাডউইথওয়ালুও ব্যবহার করতে পারেন

এক্সইসি প্রয়োজন হয় না। আপনি সরাসরি নির্বাচনের @ টিম্পলেট প্যারামিটারটি উল্লেখ করতে পারেন।


0

প্রথম - কেন এটি একটি এক্সইসি? এটা ঠিক হওয়া উচিত নয়

AS
SELECT Column_Name, ...
FROM ...
WHERE TABLE_NAME = @template

বর্তমান এসপি কি বোঝায় না? বিশেষত, এটি @ টেমপ্লেটের বর্ণচক্র মান নয়, @templet এর সাথে মিলযুক্ত একটি কলামের সন্ধান করবে । উদাহরণস্বরূপ, যদি @ স্ট্যাম্পলেট হয় তবে 'Column_Name'এটি অনুসন্ধান করবে WHERE TABLE_NAME = Column_Nameযা খুব বিরল (টেবিল এবং কলাম একই নামকরণ করতে)।

এছাড়াও, আপনি যদি না গতিশীল এসকিউএল ব্যবহার করতে হবে, আপনি ব্যবহার করা উচিত EXEC sp_ExecuteSQL(প্যারামিটার হিসেবে মান পালন) ইনজেকশন আক্রমণ (বদলে ইনপুটের সংযুক্তকরণের) থেকে প্রতিরোধ। তবে এটি এক্ষেত্রে প্রয়োজনীয় নয়।

আসল সমস্যাটি আবার দেখুন - এটি এক নজরে থেকে ঠিক আছে; আপনি কি নিশ্চিত যে আপনার চারপাশে এসপির আলাদা কপিটি নেই? এটি একটি সাধারণ ত্রুটি ...


এটি এখনও সেই পরিবর্তন নিয়ে কাজ করে না। আমার এক্সিকিউট ছিল কারণ আমি আগে এমন একটি প্রোকের সাথে কাজ করছিলাম যেখানে পরম থেকে ক্লজটি সরবরাহ করা হয়েছিল তাই আমি এই সম্পর্কে ভুল চিন্তাভাবনা করেছি। তবে আমি এখনও ত্রুটি পেয়েছি মাত্র নির্বাচন করুন
টনি পিটারসন

খুবই কৌতুহলী; টাইপসের জন্য সম্ভবত ত্রিগুণ-চেক?
মার্ক গ্র্যাভেল

0

আমি আজ এই ত্রুটিটি পেরিয়ে এসেছি যখন আমার সঞ্চিত পদ্ধতির পরামিতিগুলিতে নাল মানগুলি পাস করা হয়েছিল। আমি ডিফল্ট মান = নাল যোগ করে সঞ্চিত পদ্ধতি পরিবর্তন করে খুব সহজেই ঠিক করতে সক্ষম হয়েছি।


0

আমার একই সমস্যা ছিল, এটি সমাধান করার জন্য ঠিক আপনার প্যারামিটার সংগ্রহের সাথে আপনার সঞ্চিত পদ্ধতিগুলির মতো ঠিক একই পরামিতিটির নাম যুক্ত করুন।

উদাহরণ

ধরা যাক আপনি একটি সঞ্চিত পদ্ধতি তৈরি করেছেন:

create procedure up_select_employe_by_ID 
     (@ID int) 
as
    select * 
    from employe_t 
    where employeID = @ID

সুতরাং আপনার প্যারামিটারটিকে ঠিক যেমন আপনার সঞ্চিত পদ্ধতিতে ঠিক তেমন নামকরণ করতে ভুলবেন না

cmd.parameter.add("@ID", sqltype,size).value = @ID

আপনি যদি যান

cmd.parameter.add("@employeID", sqltype,size).value = @employeid 

তারপরে ত্রুটি ঘটে।


0

এটি বলা দরকার যে একটি সঞ্চিত প্রককে ডাকা হচ্ছে:

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