SQL在FROM中使用变量作为TABLE NAME

时间:2015-12-03 16:08:52

标签: sql-server

我们将数据库安装到不同的客户,名称可能会根据部署而改变。 我需要知道的是,您是否可以将变量用作表名。 我们所在的数据库是**** _ x,我们需要访问**** _ m。 此代码是函数的一部分。 我需要@metadb变量作为表名 - 也许使用动态SQL sp_executesql的。我只是在学习,所以请放轻松。

CREATE FUNCTION [dbo].[datAddSp] (
@cal NCHAR(30) -- calendar to use to non-working days
,@bDays INT -- number of business days to add or subtract
,@d DATETIME 
    )

RETURNS DATETIME
AS
BEGIN
DECLARE @nDate DATETIME -- the working date
,@addsub INT -- factor for adding or subtracting
,@metadb sysname

SET @metadb = db_name()
SET @metadb = REPLACE (@metadb,'_x','_m')
SET @metadb = CONCAT (@metadb,'.dbo.md_calendar_day')
SET @ndate = @d

 IF @bdays > 0
SET @addsub = 1
ELSE
SET @addsub = -1

IF @cal = '                              ' OR @cal IS NULL
SET @cal = 'CA_ON'
WHILE @bdays <> 0 -- Keep adding/subtracting a day until @bdays becomes 0
BEGIN
SELECT @ndate = dateadd(day, 1 * @addsub, @ndate) -- increase or decrease    @ndate

SELECT @bdays = CASE 
WHEN (@@datefirst + datepart(weekday, @ndate)) % 7 IN (0, 1) -- ignore if it is Sat or Sunday 
THEN @bdays
WHEN ( SELECT 1
FROM @metadb -- **THIS IS WHAT I NEED** (same for below) this table holds the holidays
WHERE mast_trunkibis_m.dbo.md_calendar_day.calendar_code = @cal AND  mast_trunkibis_m.dbo.md_calendar_day.calendar_date = @nDate AND mast_trunkibis_m.dbo.md_calendar_day.is_work_day = 0
 ) IS NOT NULL -- ignore if it is in the holiday table
 THEN @bdays
 ELSE @bdays - 1 * @addsub -- incr or decr @ndate
 END
 END
 RETURN @nDate
 END
 GO        

1 个答案:

答案 0 :(得分:1)

如果您不熟悉现有结构,最好的方法是保持所有表结构和名称相同,只需为每个客户创建一个模式,然后在模式中构建表。例如,如果您有公司:Global TruckingSuper Store,则可以为每个公司创建架构:GlobalTruckingSuperStore现在是您的架构。

假设您有productspayments表作为快速示例。您将在每个模式中创建这些表,以便最终得到如下所示的内容:

GlobalTrucking.products
GlobalTrucking.payments

SuperStore.products
SuperStore.payments

然后在应用程序层中,指定要在连接字符串中使用该连接的查询的默认架构名称。 Global Trucking的网站或应用程序将架构设置为GlobalTrucking,并且使用该连接执行任何查询时:SELECT * FROM products;实际上将自动为SELECT * FROM GlobalTrucking.products;

通过这种方式,您始终可以知道在表中查找的位置,并且每个客户都在自己的隔离空间中,拥有适当的用户权限,他们永远无法意外访问其他客户数据,而且一切都更容易导航。

以下是您的架构/用户/表创建脚本的示例(这可能不是100%正确,我只是简单地说明了这一点,我应该提到这是Oracle的方式,但SQL Server应该类似):

CREATE USER &SCHEMA_NAME IDENTIFIED BY temppasswd1;
CREATE SCHEMA AUTHORIZATION &SCHEMA_NAME
CREATE TABLE "&SCHEMA_NAME".products
(
    ProductId           NUMBER,
    Description         VARCHAR2(50),
    Price               NUMBER(10, 2),
    NumberInStock       NUMBER,
    Enabled             VARCHAR2(1)
)
CREATE TABLE "&SCHEMA_NAME".payments
(
    PaymentId           NUMBER,
    Amount              NUMBER(10, 2),
    CardType            VARCHAR2(2),
    CardNumber          VARCHAR2(15),
    CardExpire          DATE,
    PaymentTimeStamp    TIMESTAMP,
    ApprovalCode        VARCHAR2(25)
)
GRANT SELECT ON "&SCHEMA_NAME".products TO &SCHEMA_NAME
GRANT SELECT ON "&SCHEMA_NAME".payments TO &SCHEMA_NAME
;

但是,通过上述内容,您只需要保留一个脚本,以便自动添加新客户。当您运行此变量时,&SCHEMA_NAME变量将填充您为新客户的用户名/ schemaname选择的任何内容,并且每次都会创建相同的表结构。

相关问题