且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在不同的模式中创建表

更新时间:2023-12-01 15:22:22

首先,我强烈建议你不要为每个用户创建一个模式。这可能会导致很多问题,我很乐意与您讨论替代方案。



随着免责声明,我们需要转到第二个问题。您当前的方法容易受到SQL注入攻击。为了实现您的目标,我建议创建一个存储过程来处理您需要的模式和表。您将需要使用动态SQL来实现此目的。你的程序想要这样的东西:



First, I strongly urge you not to create a schema per user. This can cause a lot of issues and I'd be happy to talk alternatives with you.

With the disclaimer out of the way, we need to move onto your second issue. Your current approach is vulnerable to a SQL injection attack. To achieve what you are trying to do, I suggest creating a stored procedure that would handle creating your schema and tables you need. You will need to use dynamic SQL to achieve this. You procedure would like something like this:

IF EXISTS(SELECT * FROM sys.objects WHERE name = 'BuildCustomerSchema' AND [schema_id] = SCHEMA_ID('dbo'))
	DROP PROCEDURE dbo.BuildCustomerSchema
GO

CREATE PROCEDURE dbo.BuildCustomerSchema
	@schemaName VARCHAR(100)
AS
BEGIN
	-- The added CHAR values are used purely for formating purposes and read ability
	DECLARE @sql NVARCHAR(MAX) = N'CREATE SCHEMA [' + @schemaName + '] AUTHORIZATION [dbo];'

	-- For debug purspose, remove for production
	PRINT @sql

	-- Executes the dynamic SQL
	EXEC sp_executesql @sql

	SET @sql = 'CREATE TABLE [' + @schemaName + '].[Products](' + CHAR(13) + CHAR(10) +
		CHAR(9) + 'Id INT PRIMARY KEY,' + CHAR(13) + CHAR(10) +
		CHAR(9) + 'Name NVARCHAR(30) NOT NULL,' + CHAR(13) + CHAR(10) +
		CHAR(9) + 'ProductDesc NVARCHAR(100),' + CHAR(13) + CHAR(10) +
		CHAR(9) + 'Price DECIMAL (20),' + CHAR(13) + CHAR(10) +
		CHAR(9) + 'CategoryId INT NOT NULL)'

	-- For debug purspose, remove for production
	PRINT @sql

	-- Executes the dynamic SQL
	EXEC sp_executesql @sql
END
GO





然后,您只需要按如下方式调用存储过程:





Then, you would simply need to call the stored procedure as follows:

protected void imgNextTab2_Click(object sender, ImageClickEventArgs e)
{
    SqlConnection con1 = new SqlConnection("Data Source=admin-pc;Initial Catalog=ReportSystem;Integrated Security=True;Pooling=False");
    // Create new table in schema
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Connection = con1;
    cmd.CommandText = "dbo.BuildCustomerSchema";
    cmd.Parameters.AddWithValue("@schemaName", txtCompnyName.Text);

    try
    {
        using (con1)
        {
            con1.Open();
            cmd.ExecuteNonQuery();
            con1.Close();
            //Response.Write("successfully");
        }
    }
    catch (Exception ex)
    {
        //Response.Write(ex);
    }

    TabContainer1.ActiveTabIndex = TabContainer1.ActiveTabIndex + 1;
}





我需要用其他一些危险警告你。您将需要使用能够在数据库中创建对象的帐户。您的标准读/写帐户不会因此而削减它。随着模式数量的增加,数据库的管理将变得疯狂。您需要考虑根据模式跨多个文件对数据库进行分区(这有助于备份和还原)。您还需要非常小心地考虑这一点,因为它会影响您部署和版本控制数据库的能力(这本身就是一个非常冗长的讨论)。



我希望这样帮助。快乐的编码!



A few other dangers I need to warn you about with this. You will need use an account that has the ability to create objects in the database. Your standard read/write accounts won't cut it for this. Management of your database will get crazy as the number of schemas increase. You will need to consider partitioning the database across multiple files based on schema (this will help with backup and restore). You will also want to consider this very careful as it can affect your ability to deploy and version control the database (a very lengthy discussion in itself).

I hope this helps. Happy coding!