9

SPをチェックするための以下のコードを試しましたが、すでに存在するかどうかはわかりません。存在しない場合、私は作成しています。

しかし、表示されるたびにspは作成されません.....しかし、私のデータベースにはすでにこのspがあります。

どこで間違いをしているのか教えてください。

string checkSP = String.Format(
  "IF OBJECT_ID('{0}', 'U') IS NOT NULL SELECT 'true' ELSE SELECT 'false'", 
  "GP_SOP_AdjustTax");

SqlCommand command = new SqlCommand(checkSP, myConnection);
command.CommandType = CommandType.Text;

if (myConnection == null || myConnection.State == ConnectionState.Closed)
{
    try
    {
        myConnection.Open();
    }
    catch (Exception a)
    {
        MessageBox.Show("Error " + a.Message);
    }
}

bool Exist = false;
Exist = Convert.ToBoolean(command.ExecuteScalar());
if (Exist == false)   //false : SP does not exist
{ 
    // here i am writing code for creating SP
}
4

12 に答える 12

16

試す:

if exists(select * from sys.objects where type = 'p' and name = '<procedure name>' )

また、c#で確認できます。

string connString = "";
string query = "select * from sysobjects where type='P' and name='MyStoredProcedureName'";
bool spExists = false;
using (SqlConnection conn = new SqlConnection(connString))
{
    conn.Open();
    using (SqlCommand command = new SqlCommand(query, conn))
    {
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                spExists = true;
                break;
            }
        }
    }
}
于 2012-12-10T09:06:43.883 に答える
7

Entity FrameworkとDbContextを使用する場合:

DbContextの拡張クラスを作成します。

internal static class DbContextExtensions
{
    public static bool StoredProcedureExists(this DbContext context,
        string procedureName)
    {
        string query = String.Format(
            @"select top 1 from sys.procedures " +
              "where [type_desc] = '{0}'", procedureName);
        return dbContext.Database.SqlQuery<string>(query).Any();
    }
}

robIIIが述べたように、このコードはデータベースをハッカーに対して脆弱にするため、外部に公開しないでください(RobIIIに感謝します)。これを防ぐには、パラメーター化されたステートメントを使用します。上記の方法の問題点をここで説明します

解決策は、SQLステートメントのパラメーターとしてprocedureNameを配置することです。SQLは、文字列パラメータが目的の形式であるかどうかをチェックするため、悪意のある呼び出しを禁止します。

public static bool ImprovedExists(this DbContext dbContext, string procedureName)
{
    object[] functionParameters = new object[]
    {
        new SqlParameter(@"procedurename", procedureName),
    };
    const string query = @"select [name] from sys.procedures where name= @procedurename";
    return dbContext.Database.SqlQuery<string>(query, functionParameters).Any();
}
于 2016-05-24T12:22:23.583 に答える
5

これはMSDNで見つけました

select * from sys.objects where type_desc = 'SQL_STORED_PROCEDURE' AND name = 'Sql_PersonInsert'
于 2012-12-10T09:05:04.207 に答える
3

試す:

SELECT * 
FROM sys.objects 
WHERE object_id = OBJECT_ID(N'GP_SOP_AdjustTax') AND type in (N'P', N'PC')
于 2012-12-10T09:05:01.353 に答える
3

私の刺し傷:

  • 再利用可能な拡張方法
  • 最小限のSQL/最小限のC#
  • OPが暗黙的に要求したときに.Netから呼び出されます
  • object_id機能のおかげで速くなる可能性があります
public static bool StoredProcedureExists(this string source)
{
  using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
  {
    conn.Open();
    using (var cmd = new SqlCommand($"select object_id('{source}')", conn))
      return !cmd.ExecuteScalar().ToString().IsNullOrWhiteSpace();
  }
}
于 2016-11-04T15:51:45.950 に答える
2

次のtsqlクエリ(SQL Serverに適しています)で確認できます。

select * from sysobjects where ytype='P' and name='MyStoredProcedureName'

クエリが行を返す場合、「MyStoredProcedureName」という名前のストアドプロシージャが存在します。

そして、これがコードでそれを使用する方法です:

        //TODO: set connection string
        string connString = "";
        string query = "select * from sysobjects where ytype='P' and name='MyStoredProcedureName'";
        bool spExists = false;
        using (SqlConnection conn = new SqlConnection(connString))
        {
            conn.Open();
            using (SqlCommand command = new SqlCommand(query,conn))
            {
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        spExists = true;
                        break;
                    }
                }
            }
        }
于 2012-12-10T09:04:57.717 に答える
2
string checkSP = String.Format(
  "IF OBJECT_ID('{0}', 'U') IS NOT NULL SELECT 'true' ELSE SELECT 'false'", 
  "GP_SOP_AdjustTax");

'U'を'P'に変更すれば問題ありません。「U」を使用してユーザーテーブルをクエリします。「P」はストアドプロシージャを提供します。

于 2014-03-07T13:41:14.980 に答える
1
private static bool StoredProcedureExists(string sp)
{    
      var connString = @"<your string here>";
      var query = string.Format("SELECT COUNT(0) FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = '{0}'", sp);
      using (var conn = new SqlConnection(connString))
      {
          conn.Open();
          using (var cmd = new SqlCommand(query, conn))
          {
              return Convert.ToInt32(cmd.ExecuteScalar()) > 0;  
          }
      }
 }
于 2012-12-10T11:12:09.647 に答える
0
  • 異なるスキーマのプロシージャ名を処理します
  • 角かっこ付きとなしの名前([])
  • SQLインジェクションを回避するためにパラメーターを使用します

注:呼び出し元はSQL接続を所有しています

public static class SqlConnectionExtensions
{        
    public static Task<bool> StoredProcedureExistsAsync(this SqlConnection sqlConnection, string storedProcedureName)
    {
        string query = "SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(@storedProcedureName) AND type in (N'P', N'PC')";

        using (SqlCommand command = new SqlCommand(query, sqlConnection))
        {
            command.Parameters.AddWithValue("@storedProcedureName", storedProcedureName);
            using (SqlDataReader reader = command.ExecuteReader())
            {
                return reader.ReadAsync();
            }
        }
    }
}
于 2020-06-15T06:58:16.973 に答える
0

以下は、MySQL、SQL Server、およびOracleで機能すると思います。

SELECT * FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE='PROCEDURE'
AND (ROUTINE_SCHEMA='questionnaire' OR ROUTINE_CATALOG = 'questionnaire')
AND SPECIFIC_NAME='create_question';

使用法:

string procedureName = "create_question";
using (DbConnection conn = new SqlConnection("Server=localhost;Database=questionnaire;Trusted_Connection=True;")) // Connection is interchangeable
{
    conn.Open();
    using (var cmd = conn.CreateCommand())
    {
        cmd.CommandText = $"SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE='PROCEDURE' AND (ROUTINE_SCHEMA='{conn.Database}' OR ROUTINE_CATALOG = '{conn.Database}') AND SPECIFIC_NAME='{procedureName}';";
        return cmd.ExecuteScalar() != null;
    }
}
于 2020-09-02T09:01:32.660 に答える
0

を使用する場合はMicrosoft.SqlServer.Management.Smo

private static bool CheckIfStoredProcedureExists(Database db, string spName, string schema)
{
   db.StoredProcedures.Refresh();
   return (db.StoredProcedures[spName, schema] != null);
}

于 2021-07-01T16:13:01.527 に答える
-1

これを試して;

if object_id('YourStoredProcedureName') is null
    exec ('create procedure dbo.YourSp as select 1')
go
alter procedure dbo.YourStoredProcedure
as
于 2012-12-10T09:07:33.470 に答える