使用视图控制用户对数据访问

问:我的Microsoft Access 2000应用程序由后端的SQL Server 2000数据库写入数据。为防止Access的用户看到SQL Server 2000表中的全部数据,我想使用一种只允许用户浏览授权数据行的视图。可以创建一种限制用户访问SQL Server数据的视图吗?
答:可以。如果每位用户以唯一的用户ID登录到Access,您就可以创建一种限制用户访问SQL Server数据的视图。以下的示例语句就可以创建这样一种视图:
CREATE VIEW v_data AS
SELECT <column_list>
FROM dbo.mytable AS a
INNER JOIN dbo.authtable AS b
ON (a.Pkey = b.DataKey
AND b.userid = suser_sname())
该视图按userid限制用户的访问权。它要求您保存一份与数据表(mytable)中特定主键相匹配的用户名的表(authtable)。如果您的情况相对比较简单——您无需管理多个用户的行访问权,则您可以将userid列插入到数据表中,如下列代码所示:
CREATE VIEW v_data AS
SELECT <column_list>
FROM dbo.mytable AS a
WHERE a.userid = suser_sname()
—Microsoft SQL Server 开发团队

阅读全文

将列更新从一个表传递到另一个表

问:怎样在一个UPDATE语句中使用表B的三个列更新表A中的三个列?
答:对这个问题,您可以使用强大的关系代数。本页中的代码说明了如何组合使用FROM子句和JOIN操作,以达到用其他表中数据更新指定列的目的。在设计关系表达式时,您需要决定是否需要单一行匹配多个行(一对多关系),或者需要多个行匹配被联接表中的单一行以更新所有行(多对一关系)。
在一对多关系中,SQL Server始终使用它找到的最后一行更新数据。但是,您无法控制最后一行所在的位置。在多处理器的计算机上,查询可能是同步进行的,相同的查询最后一行的位置可能会不同。因此,Microsoft建议尽量不要使用一对多关系。
如果待更新的表与FROM子句中的表相同,并且FROM子句只包含对该表的一个引用,别名可能未被指定。如果待更新的表在FROM子句中出现了多次,只有该表的一个引用可以省略表的别名,对该表的所有其他引用必须包含一个表别名。
USE tempdb
GO
CREATE TABLE #t1 (c1 int NOT NULL, c2 char(5), c3 char(5),
c4 char(5))
GO
CREATE TABLE #t2 (c1 int NOT NULL, c2 char(5), c3 char(5),
c4 char(5))
GO
--数据赋值
INSERT #t1 values (1,'hello','there','fred')
INSERT #t2 values (1,'how','are','you?')
--更新数据
UPDATE #t1 SET #t1.c2 = #t2.c2, #t1.c3 = #t2.c3,
#t1.c4 = #t2.c4
FROM #t2
WHERE #t1.c1 = #t2.c1
--检查结果
SELECT * FROM #t1
—Microsoft SQL Server开发团队

阅读全文

在PHP中操作MySQL要注意哪些问题

1、分号的例外

  在MySQL中,每一行命令都是用分号(;)作为结束的,但是当一行MySQL命令被插入在PHP代码中时,最好把后面的分号省略掉,例如:

mysql_query ("INSERT INTO tablename (first_name, last_name) VALUES ('$first_name', '$last_name')");

  这是因为PHP也是以分号作为一行的结束的,额外的分号有时会导致PHP 的语法分析器做出错误的分析,所以还是省略掉的好。在这种情况下,虽然省略了分号,但是 PHP 在执行 MySQL 命令时会自动加上分号。

  另外还有一个不要加分号的情况。当你想把要字段的竖着排列显示下来,而不是像通常的那样横着排列时,你可以用 G 来结束一行SQL 语句,这时就用不上分号了,例如:

    SELECT * FROM PENPALS WHERE USER_ID = 1G

  2、TEXT、DATE、和 SET 数据类型

  TEXT 不是一种数据类型,应该是" LONG VARCHAR "或者" MEDIUMTEXT "。

  DATE 数据类型的格式是 YYYY-MM-DD ,比如: 2001-10-01 。你可以很轻易的用 date 函数来得到这种格式的当前系统时间:

    date("Y-m-d")

  并且,在 DATA 数据类型之间可以作减法,得到相差的时间天数:

    $age = ($current_date - $birthdate);

  集合 SET 是一个有用的数据类型,它和枚举 ENUM 有点相似,只不过是 SET 能够保存多个值而 ENUM 只能保存一个值而已。而且, SET 类型最多只能够有 64 个预定的值,而 ENUM 类型却能够处理最多 65,535 个预定义的值。而假如需要有大于 64 个值的集合,该怎么办呢?这时就需要定义多个集合来一起解决这个问题了。

  3、通配符

  SQL 的通配符有两种:" * "和" % "。分别用在不同的情况下。例如:假如你想看到数据库的所有内容,可以像这样来查询:

    SELECT * FROM dbname WHERE USER_ID LIKE '%';

  这儿,两个通配符都被用上了。他们表示相同的意思 ?? 都是用来匹配任何的字符串,但是他们用在不同的上下文中。" * "用来匹配字段名,而" % "用来匹配字段值。另外一个不轻易引起注重的地方是" % "通配符需要和 LIKE 要害字一起使用。

  还有一个通配符,就是下划线" _ ",它代表的意思和上面不同,是用来匹配任何单个的字符的。

  4、NOT NULL 和空记录

  假如用户在没有填任何东西的情况下按了 submit 按钮,会怎样呢?假如你确实需要一个值,那么可以用客户端脚本或者服务器端脚本来进行数据验证,这一点在前面已经说过了。但是,在数据库中却是答应一些字段被空出来什么也不填。对此类纪录, MySQL 将进行以下步骤:

  插入值 NULL ,这是缺省的操作。

  假如你在字段定义中为之声明了 NOT NULL (在建立或者修改这个字段的时候), MySQL 将把这个字段空出来什么东西也不填。

  对于一个 ENUM 枚举类型的字段,假如你为之声明了 NOT NULL , MySQL 将把枚举集的第一个值插入到字段中。也就是说, MySQL 把枚举集的第一个值作为这个枚举类型的缺省值。

  一个值为 NULL 的纪录和一个空纪录是有一些区别的。 % 通配符可以匹配空纪录,但是却不能匹配 NULL 纪录。在某些时候,这种区别会造成一些意想不到的后果。就经验而言,任何字段都应该声明为 NOT NULL 。这样下面的 SELECT 查询语句就能够正常运转了:

  if (!$CITY) {$CITY = "%";}
  $selectresult = mysql_query ("SELECT * FROM dbname
  WHERE FIRST_NAME = ' Bill '
  AND LAST_NAME = ' Gates '
  AND CITY LIKE '$CITY'
  ");

  在第一行中,假如用户没有指定一个 CITY 值,那么就会用通配符 % 来代入 CITY 变量,这样搜索时就会把任何的 CITY 值都考虑进去,甚至包括那些 CITY 字段为空的纪录。

  但是假如有一些纪录,它的 CITY 字段值是 NULL ,这时问题就出现了。上面的查询是不能够找到这些字段的。问题的一个解决办法可以是这样:

  if (!$CITY) {$CITY = "%";}
  $selectresult = mysql_query ("SELECT * FROM dbname
  WHERE FIRST_NAME = ' Bill '
  AND LAST_NAME = ' Gates '
  AND (CITY LIKE '$CITY' OR CITY IS NULL)
  ");

  注重在搜索 NULL 时,必须用" IS "要害字,而 LIKE 时不会正常工作的。

  在最后要提到的是,假如你在加入或者修改一个新的字段之前,数据库中已经有了一些记录了,这时新加入的字段在原来的纪录中的值,可能是 NULL ,也可能为空,在这种情况下,使用 SELECT 查询要非凡的小心。

阅读全文

维护Sql Server中表的索引

--第一步:查看是否需要维护,查看扫描密度/Scan Density是否为100%
declare @table_id int
set @table_id=object_id('表名')
dbcc showcontig(@table_id)
--第二步:重构表索引
dbcc dbreindex('表名',pk_索引名,100)
--重做第一步,如发现扫描密度/Scan Density还是小于100%则重构表的所有索引
--杨铮:并不一定能达100%。
dbcc dbreindex('表名','',100)

阅读全文

将XML文件导入SQL Server 2000

问:怎样才能将XML文件导入SQL Server 2000?
答:将XML文件导入SQL Server有若干种方法,这里提供其中的3种:
大容量装载COM接口。如果需要将文档的实体和属性析取到关系表中,最快的方法就是使用SQL Server 2000 Extensible Markup Language 3.0 Service Pack 1(SQLXML 3.0 SP1)提供的大容量装载COM接口。大容量状态COM接口包含在SQLXML 3.0 SP1的免费下载中。
textcopy.exe命令行实用工具。如果不希望将文档的实体和属性析取到关系表中,您可以使用textcopy.exe命令行实用工具。Textcopy.exe是将文本和image数据类型从单一服务器行或列移入或移出的优秀工具。
数据转换服务(DTS)。如果XML文档很简单,您可以使用DTS将信息逐行析取到表中。这一方法要求您将XML文件定义为输入数据源,将数据库表定义为输出数据源,并编写ActiveX脚本剖析"<"和">"方式的字符输入,以析取实体、属性及其值。
 
—Microsoft SQL Server开发团队

阅读全文

打开UDP端口1434以浏览命名实例

:本地的一个ISP托管了我们的SQL Server,但是我不能看到或连接到运行在该计算机上的命名实例。我知道SQL Server 2000命名实例不使用TCP/IP 1433端口,并且确定该SQL Server实例所使用的TCP/IP端口是打开的。您有什么建议吗?

阅读全文

SQL SERVER日志清除的两种方法

方法一
一般情况下,SQL数据库的收缩并不能很大程度上减小数据库大小,其主要作用是收缩日志大小,应当定期进行此操作以免数据库日志过大
1、设置数据库模式为简单模式:打开SQL企业管理器,在控制台根目录中依次点开Microsoft SQL Server-->SQL Server组-->双击打开你的服务器-->双击打开数据库目录-->选择你的数据库名称(如论坛数据库Forum)-->然后点击右键选择属性-->选择选项-->在故障还原的模式中选择“简单”,然后按确定保存
2、在当前数据库上点右键,看所有任务中的收缩数据库,一般里面的默认设置不用调整,直接点确定
3、收缩数据库完成后,建议将您的数据库属性重新设置为标准模式,操作方法同第一点,因为日志在一些异常情况下往往是恢复数据库的重要依据
方法二
SET NOCOUNT ON
DECLARE @LogicalFileName sysname,
@MaxMinutes INT,
@NewSize INT
USE tablename -- 要操作的数据库名
SELECT @LogicalFileName = 'tablename_log', -- 日志文件名
@MaxMinutes = 10, -- Limit on time allowed to wrap log.
@NewSize = 1 -- 你想设定的日志文件的大小(M)
-- Setup / initialize
DECLARE @OriginalSize int
SELECT @OriginalSize = size
FROM sysfiles
WHERE name = @LogicalFileName
SELECT 'Original Size of ' db_name() ' LOG is '
CONVERT(VARCHAR(30),@OriginalSize) ' 8K pages or '
CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) 'MB'
FROM sysfiles
WHERE name = @LogicalFileName
CREATE TABLE DummyTrans
(DummyColumn char (8000) not null)
DECLARE @Counter INT,
@StartTime DATETIME,
@TruncLog VARCHAR(255)
SELECT @StartTime = GETDATE(),
@TruncLog = 'BACKUP LOG ' db_name() ' WITH TRUNCATE_ONLY'
DBCC SHRINKFILE (@LogicalFileName, @NewSize)
EXEC (@TruncLog)
-- Wrap the log if necessary.
WHILE @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) -- time has not expired
AND @OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName)

阅读全文

如何使用系统管理员帐户管理多个开发人员?

问:在我们的开发环境下,每个人都有系统管理员(sa)密码,5个组使用一个数据库。在某个开发人员不小心删除了数据后,我没有办法确定谁删除哪一块数据。当开发人员更新数据库中的数据时,如何审核工作站或登录ID?
答:因为您工作于开发环境下,使用SQL事件探查器和服务器跟踪所带来的性能损失并不会影响生产环境,所以您可以设置一个服务器跟踪,在后台将信息记录在一个表中。然后,您可以搜索该表以确定谁删除了数据。
显然,一次为多个用户分配sa账户会带来许多问题。以下是您应该采取的一些措施:
为每个开发团队创建该数据库的一份拷贝,为每个团队提供一个仅数据库拥有者才有访问权的账户。这样的话,他们就不会互相影响了。
 
如果每个开发人员都需要sa访问权(例如运行SQL事件探查器跟踪),并且您运行的是SQL Server 2000 Enterprise或Developer Edition,您可以为每个团队提供SQL Server的一个实例及其专用的sa密码。
 
考虑为每个项目设置一个开发环境,并以一个集成环境的方式由一个版本数据库管理员对所有项目间冲突进行管理。这样的话,因为架构改变脚本在进入集成环境之前已经经过了测试,生产版本的质量将有所改善。
 
—The Microsoft SQL Server开发团队

阅读全文

SQL Server2000数据库文件损坏时如何恢复

SQL Server2000中,如果数据库文件(非系统数据库文件)遇到错误的时候,我们该怎么办。以下是笔者以前的笔记。仅适用于非master,msdb的数据库。
说明如下:
1 建一个测试数据库test(数据库类型为完全)
2 建一个表,插入点记录
create table a(c1 varchar(2))
go
insert into a values('aa')
go
insert into a values('bb')
go
3 作完全备份,到文件test_1.bak
4 在作一点修改
insert into a values('cc')
go
create table b(c1 int)
go
insert into b values(1)
go
insert into b values(2)
go
5 shutdown 数据库服务器
6 用ultraedit编辑数据库文件test_data.mdf,随便修改点字节内容,相当于数据库遭到致命的损坏。
7 启动数据库,并且运行企业管理器,点开数据库,看到test变成灰色,而且显示置疑。
8 运行isql -SLocalhost -Usa -P
1> backup log test TO DISK='D:Program FilesMicrosoft SQL ServerMSSQLBACKUP
est_2.bak' WITH NO_TRUNCATE
2>go
已处理 2 页,这些页属于数据库 'test' 的文件 'TEST_Log'(位于文件 1 上)。
BACKUP LOG 操作成功地处理了 2 页,花费了 0.111 秒(0.087 MB/秒)。
9 进行恢复最老的完全备份
1> RESTORE DATABASE test FROM DISK='D:Program FilesMicrosoft SQL ServerMSSQL
BACKUP est_1.bak' WITH NORECOVERY
2> go
已处理 96 页,这些页属于数据库 'test' 的文件 'TEST_Data'(位于文件 1 上)。
已处理 1 页,这些页属于数据库 'test' 的文件 'TEST_Log'(位于文件 1 上)。
RESTORE DATABASE 操作成功地处理了 97 页,花费了 0.107 秒(7.368 MB/秒)。
10 恢复最近的日志
1> RESTORE LOG test FROM DISK='D:Program FilesMicrosoft SQL ServerMSSQLBACKU
P est_2.bak' WITH RECOVERY
2> go
已处理 2 页,这些页属于数据库 'test' 的文件 'TEST_Log'(位于文件 1 上)。
RESTORE LOG 操作成功地处理了 2 页,花费了 0.056 秒(0.173 MB/秒)。
数据已经完全恢复了,可以使用了。
select * from a
go
总结,DBA应该有一个完善的数据库备份计划。本例中,如果没有一个完全备份的话,数据库的恢复就不可能

阅读全文

确保所有的非空(Non-NULL)值都是唯一的

问:我的SQL Server表的一列允许NULL值。我希望在其值为非NULL时,该列是唯一的。怎样才能以编程的方式实现这一行为?如果在该列上设置一个UNIQUE 约束,我只能包含一个值为NULL的记录。我正在使用触发器实现这一约束,您可以推荐一个更简单的方法以保证所有的非NULL值唯一吗?
答:SQL Server没有实现非NULL值唯一性的内建机制,因此您需要通过自定义的CHECK约束来实现这一机制。例如,以下一段编码实现了您所需要的功能:
USE tempdb
CREATE table t1 (c1 int NULL, c2 char(5) NULL)
CREATE trigger mytrigger on t1 for insert, update as
BEGIN
IF (select max(cnt) from (select count(i.c1)
as cnt from t1, inserted i where t1.c1=i.c1 group
by i.c1) x) > 1
ROLLBACK TRAN
END
在SQL Server 2000中,您还可以使用INSTEAD OF触发器来实现这一功能。有关INSTEAD OF触发器的详细信息,请参阅以下文章。如需访问这些文章,请访问SQL Server 杂志网站,在InstantDoc框中输入InstantDoc号,然后点击Go。相关文章如下:
Tricks with INSTEAD OF Triggers; InstantDoc number 15828
INSTEAD OF Triggers on Views; InstantDoc number 15791
INSTEAD OF Triggers; InstantDoc number 15524
—SQL Server MVPs

阅读全文

如何把access转换到mysql

access 只能在 windows 下使用这一致命的特性让我深恶痛绝,痛下决心要把 access 转换到 mysql,但是从网上找了很多文章,都没有直接转换的东西。听说可以利用odbc转,就尝试了一下。
 
先安装好mysql,myodbc,建一个mysql的空数据库,在odbc管理中加上这个数据库,指定名称。
 
用access2000打开数据库,然后选导出,选odbc,选机器数据源,选中自己刚才建立好的mysql odbc 数据源,确定后导出。
 
一次只能倒一个表。
 
。。。。。。。。。。
 
终于完了,现在成功了吗?
把程序中的数据源改到刚倒好的mysql odbc上,发现到处都是错误,原来mysql对表的大小写有区分,改了程序后,运行感觉不错,速度也可以。
 
不对,怎么又错了,这个ID怎么是空的???
原来这个倒入的数据库不支持自动递增的功能。

继续到mysql的目录,bin下运行 mysqldump 倒出所有的结构和数据到一个文件 my.sql然后编辑 my.sql,修改所有的 CREATE TABLE 语句,
ID int not null auto_increment, primary key (ID), 这样ID就相当于access中的自动编号数据类型了,在 mysql/bin 下运行mysql,drop掉原来的数据库,再source一下刚才修改过的这个my.sql所有数据恢复进去,好,这下一切搞定,程序比往常要快了许多,尤其是论坛部分。
 
注:此次操作均在 windows 2000 下进行。

阅读全文

执行一个安全的SQL Server安装

收集和分发数据是网络管理的职责之一,而且必须确保这些数据的准确性和安全性。不管它们是什么操作系统,数据库服务器需要特殊的管理以保证操作上的安全性。

良好的安全性开始于安装。现在让我们看一看如何才能在开始的时候就获得SQL Server的安全性。
安装
在开始安装之前,先定位到终端路由器或者防火墙,将UDP和TCP端口1433和1434指明为SQL Server的IP地址,这将有助于在安装的时候防止SQL injection弱点。
请不要在一个域控制器(domain controller)上安装SQL Server,一个程序的弱点可以导致危及整个域。在安装程序的转移数据之前,你最好在一个具有完全补丁修补之后的操作系统上安装SQL Server。
SQL Server服务应该运行于独立的当地帐号之下。这样,即使如果有人破坏程序,其它的服务器也可以不受影响。
如果服务器想要为一个基于Windows的网络服务,与服务器的所有连接都需要Windows认证。这将使得用户不再有必要记住其它连接的密码,从而减轻了用户的负担。

服务帐号
在通常情况下,服务帐号十分注意分配给它们的权限。SQL Server使用两种帐号:SQL Server Engine和SQL Server Agent。这两种帐号都作为一个具有常规帐号权限的域用户而运行。
如果你使用SQL Server认证,而不是使用Windows认证,或者如果你的服务器运行的是ActiveX脚本或CmdExec作业(比如,操作系统命令或者.bat,.cmd,.com,或.exe的可执行程序),SQL Server Agent帐号将需要当地Windows管理员权限。
注意:如果你需要改变与SQL Server服务有关的帐号,可以使用SQL Server企业管理者(SQL Server Enterprise Manager)。企业管理者将对SQL Server使用的文件和注册表键设置合适的权限。不要使用控制面板上MMC的Services applet来更改这些帐号。
安装之后

通过运行微软Killpwd.exe程序,可以清除在安装过程中保存在不同安装文件中的纯文本sysadmin密码。
当从新服务器中清除安装文件之后,运行Microsoft Baseline Security Analyzer (MBSA)。这一工具能够扫描和测试安装中产生的问题,这些问题包括:
过多的sysadmin成员都想作为服务器角色。
分配建立CmdExec作业的权限。
空白的或者琐屑的密码。
脆弱的认证方式。
分配给管理者组的过多的权限。
运行于域控制器的系统的SQL Server。
每一组的不合适的配置。
SQL Server服务帐号的不合适的配置。

阅读全文