home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1994 June / NEBULA_SE.ISO / Documents / FAQ / Sybase-faq < prev    next >
Encoding:
Internet Message Format  |  1993-08-15  |  74.2 KB

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.kei.com!ddsw1!meaddata!news
  2. From: davidp@meaddata.com (David Pledger)
  3. Newsgroups: comp.databases.sybase,comp.databases,comp.answers,news.answers
  4. Subject: comp.databases.sybase Frequently Asked Questions (FAQ)
  5. Supersedes: <sybfaq_745104004@meaddata.com>
  6. Followup-To: comp.databases.sybase
  7. Date: 13 Aug 1993 12:47:38 GMT
  8. Organization: Strategic Data Systems, Dayton, OH
  9. Lines: 2196
  10. Approved: news-answers-request@mit.edu
  11. Distribution: world
  12. Expires: 26 Sep 1993 12:47:35 GMT
  13. Message-ID: <sybfaq_745246055@meaddata.com>
  14. NNTP-Posting-Host: ibis.meaddata.com
  15. Summary: This monthly posting contains a list of Frequently Asked Questions 
  16.          about the Sybase Relational Database Management System (RDBMS).
  17. Keywords: Sybase,RDBMS,FAQ,Frequently Asked Questions,isql,T-SQL
  18. Xref: senator-bedfellow.mit.edu comp.databases.sybase:2786 comp.databases:27841 comp.answers:1593 news.answers:11333
  19.  
  20. Archive-name: sybase-faq
  21. Last-modified: 1993/08/11
  22. Version: 1.0
  23.  
  24.  
  25.                            S Y B A S E
  26.  
  27.               Frequently Asked Questions (FAQ), Version 1.0
  28.  
  29.  
  30. Copyright 1993 by David W. Pledger.
  31.  
  32.     All rights reserved. Permission for non-commercial distribution is 
  33. hereby granted, provided that this file is distributed intact, 
  34. including this copyright notice and the version information above. 
  35. Permission for commercial distribution may be obtained from the 
  36. author. SHARE THIS INFORMATION FREELY AND IN GOOD FAITH. DO NOT 
  37. DISTRIBUTE MODIFIED VERSIONS OF THIS DOCUMENT.
  38.  
  39. ======================================================================
  40.  
  41.                   T A B L E   O F   C O N T E N T S
  42.  
  43.  
  44. 1.0    Introduction
  45.  
  46.   1.1    Summary of changes
  47.  
  48.   1.2    Posting Hints
  49.  
  50.   1.3    Introduction
  51.  
  52.   1.4    Acknowledgments
  53.  
  54.   1.5    Terms and Abbreviations
  55.  
  56. 2.0    General Questions
  57.  
  58.     Question 2.0-1:  How can I get in touch with Sybase?
  59.  
  60.     Question 2.0-2:  What periodicals exist for Sybase?
  61.  
  62.     Question 2.0-3:  What's a good book about Sybase?
  63.  
  64.     Question 2.0-4:  Who are my local user groups and how can I get 
  65.     in touch with them?
  66.  
  67.     Question 2.0-5:  Has anyone implemented a C++ class library for 
  68.     Sybase?
  69.  
  70.     Question 2.0-6:  What are good front-ends for Sybase?
  71.  
  72.     Question 2.0-7:  Does Sybase support the X/Open XA interface?
  73.  
  74.     Question 2.0-8:  Does Sybase support ODBC (Microsoft Windows Open 
  75.     Database Connectivity)?
  76.  
  77. 3.0    Database Server
  78.  
  79.   3.1    Sybase ISQL
  80.  
  81.     Question 3.1-1:  How do I prevent isql output from wrapping around 
  82.     at 80 columns?
  83.  
  84.     Question 3.1-2:  How do I send isql output to a file? The -o switch 
  85.     doesn't work.
  86.  
  87.     Question 3.1-3:  Can I submit a multiline statement as input to 
  88.     isql without creating a file with the commands in it 
  89.     first>
  90.  
  91.     Question 3.1-4:  How do I prevent the password from being 
  92.     displayed when someone does a UNIX *ps* command?
  93.  
  94.     Question 3.1-5:  I want to add some new features to isql. Does 
  95.     anyone have the source code?
  96.  
  97.   3.2    Sybase Transact-SQL
  98.  
  99.     Question 3.2-1:  What exactly does sp_primarykey, sp_foreignkey, 
  100.     and sp_commonkey do?
  101.  
  102.     Question 3.2-2:  I want to write a new system stored procedure 
  103.     that gives me information not provided by the existing 
  104.     stored procedures. How do I make these available to all 
  105.     users like the provided stored procedures.
  106.  
  107.     Question 3.2-3:  How can I do a "row level select" (built-in "if" 
  108.     function) without having to create a temporary table, 
  109.     etc.?
  110.     
  111.     Question 3.2-4:  How do I use a table name as a parameter to a 
  112.     stored procedure, which will then run a query on the 
  113.     specified table?
  114.     
  115.     Question 3.2-5:  Can you change the definition of a table to 
  116.     prohibit nulls once you've defined it to permit them?
  117.     
  118.     Question 3.2-6:  Is there a simple way to solve the Sybase 
  119.     ""matching quotes"" requirement in a character field?
  120.     
  121.     Question 3.2-7:  How can I do a case-insensitive search?
  122.     
  123.     Question 3.2-8:  How do wildcards used for pattern matching work 
  124.     in the context of the LIKE operator.
  125.     
  126.     Question 3.2-9:  How do I put a unique serial number on a table?
  127.     
  128.     Question 3.2-10:  Is it possible to explicitly lock a table in 
  129.     Sybase to prevent other users from inserting into the 
  130.     table for a very short time?
  131.     
  132.     Question 3.2-11:  Exactly when does a trigger fire?
  133.     
  134.     Question 3.2-12:  Is there an easy way within the server to 
  135.     determine how many days are in the current month?
  136.     
  137.   3.3    Sybase Bulk Copy
  138.     
  139.     Question 3.3-1:  When using BCP to copy a database, is the copy 
  140.     equivalent to the original in terms of performance?
  141.     
  142.     Question 3.3-2:  Can BCP load null dates?
  143.     
  144.   3.4    Sybase Backup and Recovery
  145.     
  146.     Question 3.4-1:  How can I dump more than one database to a single 
  147.     tape?
  148.     
  149.   3.5    Upgrading the Sybase Server
  150.     
  151.     Question 3.5-1:  I'm upgrading from version <x> and/or operating 
  152.     system <p> to version <y> and/or operating system <q>. 
  153.     Any advice?
  154.     
  155.   3.6    Sybase Security
  156.     
  157.     Question 3.6-1:  What different mechanisms are there to control 
  158.     Sybase security?
  159.     
  160.   3.7    Sybase Database Administration
  161.     
  162.     Question 3.7-1:  Why does the transaction log on the model 
  163.     database keep filling up?
  164.     
  165.     Question 3.7-2:  Why does my transaction log fill up even when I 
  166.     have allocated lots of space for it?
  167.     
  168.     Question 3.7-3:  Is there a way to trun off logging altogether? 
  169.     How about putting the transaction logs on `/dev/null'? 
  170.     How does tempdb avoid logging?
  171.     
  172.     Question 3.7-4:  Is there any reason not to have `truncate log on 
  173.     checkpoint' turned on for the model database?
  174.     
  175.     Question 3.7-5:  Why doesn't the Sybase kill command work?
  176.     
  177.     Question 3.7-6:  What are some of the undocumented features of 
  178.     DBCC?
  179.     
  180.     Question 3.7-7:  What are the trace flags used for and what are 
  181.     some of the more common flags.
  182.     
  183.     Question 3.7-8:  Is there a way to accurately estimate how much 
  184.     space a table and its indeces are going to take?
  185.     
  186.     Question 3.7-9:  Can I recover a database that comes up marked 
  187.     `SUSPECT'?
  188.     
  189.     Question 3.7-10:  My database tables often get locked by the 
  190.     client's hung workstation. Is there a way that I can 
  191.     unlock those locked tables?
  192.     
  193.     Question 3.7-11:  Does the server sort order affect performance? 
  194.     Is binary sort order the fastest way?
  195.     
  196.     Question 3.7-12:  Does Sybase have a memory limit?
  197.     
  198.   3.8    Sybase Performance Tuning
  199.     
  200.     Question 3.8-1:  How much overhead do variable size and NULL 
  201.     columns require?
  202.     
  203.     Question 3.8-2:  How does the query optimizer work? Does the 
  204.     ordering of tables in the from clause or the conditionals 
  205.     in the where clauses affect the performance of the query?
  206.     
  207.     Question 3.8-3:  Can I force the optimizer to access tables in a 
  208.     certain order or to use a particular index?
  209.     
  210.     Question 3.8-4:  Does dropping an index cause recompilation of a 
  211.     stored procedure?
  212.     
  213.     Question 3.8-5:  Does the time for a select that yields 1000 rows 
  214.     from a table of 10,000 differ much from the same select 
  215.     when the table contains 100,000 rows?
  216.     
  217.   3.9    Sybase Network Issues
  218.     
  219.     Question 3.9-1:  How can I make Sybase talk to two separate 
  220.     ethernet interfaces on our server?
  221.     
  222.     Question 3.9-2:  Can I use Sybase over PPP (Peer-to-Peer 
  223.     protocol)?
  224.     
  225. 4.0    Open Server
  226.  
  227. 5.0    Open Client
  228.  
  229.     Question 5.0-1:  How can I use the Sybase Open Client with my C++ 
  230.     code?
  231.     
  232.     Question 5.0-2:  Which C compilers is the DOS version of the Open 
  233.     Client software compatible with?
  234.  
  235. 6.0    APT
  236.  
  237.     Question 6.0-1:  Is it possible to place other visible fields on 
  238.     top of invisible fields, or do I have to have big open 
  239.     spaces?
  240.  
  241. 7.0    DWB
  242.  
  243. 8.0    Report Writer
  244.  
  245. 9.0    Third Party Applications
  246.  
  247. 9.1    User Interface Client Applications
  248.  
  249. 9.2    Class Libraries
  250.  
  251. 9.3    Other Miscellaneous Products and Tools
  252.  
  253.  
  254.  
  255. ======================================================================
  256.  
  257. 1.0  Introduction
  258.  
  259. ======================================================================
  260.  
  261. 1.1  Summary of changes
  262.  
  263.     This is the Sybase FAQ, version 1.0. This does not supercede any 
  264. other version and is being issued as a draft. Updates will be posted 
  265. monthly.
  266.  
  267. ======================================================================
  268.  
  269. 1.2  Posting Hints
  270.  
  271. Before posting to comp.databases.sybase, please consider that many 
  272. people in Netland are reading News using an 80 column display. If you 
  273. set your right margin to 75 it will make your article much easier to 
  274. read for those people.
  275.  
  276. ======================================================================
  277.  
  278. 1.3  Introduction
  279.  
  280.     This is the first release of the Sybase FAQ. It undoubtedly contains 
  281. typos, mistakes, and other misinformation. Comments and corrections 
  282. are welcomed and encouraged. Please direct all comments to 
  283. davidp@meaddata.com. Include the phrase `Sybase FAQ' as the subject of 
  284. your message. I will include your changes as appropriate and give 
  285. credit where credit is due.
  286.  
  287.     The intent of this document is to answer many of the frequently asked 
  288. questions about the various products that Sybase offers. The emphasis 
  289. of this FAQ is on the database server, primarily because that is my 
  290. expertise. I will include questions and discussion on Open Server, Open 
  291. Client, and other topics as I receive pertinent information.
  292.  
  293.     This article is posted to the news group comp.database.sybase monthly. 
  294. This article is also cross-posted to news groups news.answers, 
  295. comp.databases, and comp.answers.
  296.  
  297.     Please send me a note if you have any particular topic you would like 
  298. to see addressed or any comments on the content or organization of this 
  299. document. I extracted much of this information from both personal 
  300. experience and from posts which have occurred during the past year. I 
  301. did not keep the name or email address of much of the information I have 
  302. archived, so if you see something that you wrote, but weren't given 
  303. credit for, drop me a line and I give you the proper credit.
  304.  
  305.     This FAQ is archived at the ftp site: 
  306.  
  307. straylight.acs.ncsu.edu:/pub/ sybase
  308.  
  309.     As an aside, you might want to refer to the newsgroup 
  310. news.newusers.questions for translations of IMHO, IMO, BTW, wrt, 8-), 
  311. etc.
  312.  
  313. ======================================================================
  314.  
  315. 1.4  Acknowledgments
  316.  
  317.     The following individuals have made significant contributions 
  318. toward the compilation of this document.
  319.  
  320. Name            Email Address
  321. ---------------------------------------------
  322. David Pledger            davidp@meaddata.com
  323. Tom Warfield            twarfield@vnunet.uucp
  324. David Joyner            nsysdbj@acs.ncsu.edu
  325.  
  326. ======================================================================
  327.  
  328. 1.5  Terms and Abbreviations
  329.  
  330.     The following list contains terms and abbreviations that are used 
  331. within this document. Reference the glossary, section 1.6 for a detailed 
  332. description of the meaning of each of the items identified below.
  333.  
  334. APT - Application Programming Toolkit (Sybase Product)
  335.  
  336. dbid - Database Id
  337.  
  338. DDL - Database Definition Language (SQL Create & Index 
  339. Statements)
  340.  
  341. DML - Database Manipulation Language (SQL Insert, Update, 
  342. Delete, & Select)
  343.  
  344. DWB - Data WorkBench (Sybase Product)
  345.  
  346. EBF - Emergency Bug Fix
  347.  
  348. GAM - global allocation map
  349.  
  350. indid- Index Id
  351.  
  352. LFS - logical file system
  353.  
  354. LRU - least recently used
  355.  
  356. OAM - Object Allocation Map
  357.  
  358. objid - Object Id
  359.  
  360. PSS - Process Slot Structure
  361.  
  362. Rid - Row Id
  363.  
  364. Rollup - Collection of bug fixes issued as an upgrade release.
  365.  
  366. SPID - Server Process Id
  367.  
  368. sproc - Stored Procedure
  369.  
  370. SQR - Structured Query Report Writer (Sybase Product)
  371.  
  372. STS - Sybase Technical Support
  373.  
  374. T-SQL - Transact SQL, Sybase's version of SQL with extensions.
  375.  
  376. vdevno- virtual device number
  377.  
  378. ======================================================================
  379.  
  380. 2.0  General Questions
  381.  
  382. ---------------------------------------------------
  383. Question 2.0-1:  How can I get in touch with Sybase?
  384.  
  385. Answer:    
  386.  
  387. Corporate Address
  388.     Sybase, Inc.
  389.     6475 Christie Avenue
  390.     Emeryville, CA 94608
  391.     Phone:
  392.  
  393. Dial Up Service:
  394.     INSIGHT 1-510-601-4991.
  395.     To register, dial up that number with your computer/modem and have 
  396. your company number handy. Your contact id helps. Type "new" at the 
  397. login prompt to create a new account.
  398.  
  399. Support Renewals
  400.     1-510-596-4524
  401.  
  402. Customer Service
  403.     1-510-596-3333. This is the main customer service line. They 
  404. can answer or direct any non-technical, non-support renewal 
  405. questions and expedite service.
  406.  
  407. ---------------------------------------------------
  408. Question 2.0-2:  What periodicals exist for Sybase?
  409.  
  410. Answer:    The following magazines are either Sybase specific or related 
  411. to relational database design.
  412.  
  413. SQL Forum
  414. PO Box 240
  415. Lynnwood, WA 98046-0240
  416. Phone (206)382-6607
  417. Published bi-monthly (6 issues yearly)
  418. us$60/year.
  419.  
  420. The Relational Journal
  421. Codd & Date, Inc.
  422. 1772A Technology Drive
  423. San Jose, CA 95110-1306
  424. Phone: (408) 441-6400
  425. Published bi-monthly
  426. us$249.00/year
  427.  
  428. ---------------------------------------------------
  429. Question 2.0-3:  What's a good book about Sybase?
  430.  
  431. Answer:    Consider the following texts.
  432.  
  433. A Guide to Sybase and SQL Server
  434. McGoveran and Date
  435. Addison Wesley Publishers
  436.  
  437. Sybase Architecture and Administration
  438. John Kirkwood
  439. Ellis Horwood Publishers
  440. ISBN 0-13-100330-5
  441.  
  442. ---------------------------------------------------
  443. Question 2.0-4:  Who are my local user groups and how can I get in touch 
  444. with them?
  445.  
  446. Answer:    There are a number of groups in different areas of the 
  447. country, some of which include...
  448.  
  449. BAWASLUG: Baltimore / Washington Area Sybase Local User's Group
  450. Meets Quarterly
  451. Contact:
  452.  
  453. ---------------------------------------------------
  454. Question 2.0-5:  Has anyone implemented a C++ class library for Sybase?
  455.  
  456. Answer:    A class library in this context provides a mechanism for 
  457. allowing an object-oriented language such as C++ to access and 
  458. manipulate database objects. Some of these class libraries provide an 
  459. abstraction of multiple databases, such as Oracle, Ingres, and Sybase, 
  460. to provide a single library of routines to access all of these different 
  461. products.
  462.  
  463. See the archive ftp.acs.ncsu.edu:/pub/sybase++ for info. Section 9.2 
  464. below, also provides sources of commercial products that have 
  465. implemented database class libraries.
  466.  
  467. ---------------------------------------------------
  468. Question 2.0-6:  What are good front-ends for Sybase?
  469.  
  470. Answer:    See section 9 of this document.
  471.  
  472. ---------------------------------------------------
  473. Question 2.0-7:  Does Sybase support the X/Open XA interface?
  474.  
  475. Answer:    Currently, Sybase does not support the X/Open XA interface. 
  476. You cannot use it with either Encina or Tuxedo for global transaction 
  477. management in the X/Open DTP environment. System 10 is supposed to be XA 
  478. complient.
  479.  
  480. However, you CAN use it with TOP END, NCR's TP Monitor. TOP END's XA 
  481. Veneer Technology allows Sybase's non-XA compliant DBMS product to 
  482. participate in global transactions in an X/Open DTP environment. This XA 
  483. Veneer DOES make use of Sybase's two-phase commit feature.
  484.  
  485. Ray Niety, ray.nieto@sandiegoca.ncr.com
  486.  
  487. ---------------------------------------------------
  488. Question 2.0-8:  Does Sybase support ODBC (Microsoft Windows Open 
  489. Database Connectivity)?
  490.  
  491. Answer:    Yes, but you may need to install additional stored procedures 
  492. in the master database to get it to work. If you are running Sybase 
  493. under Novell, these come pre-installed.
  494.  
  495. ======================================================================
  496.  
  497. 3.0  Database Server
  498.  
  499. ======================================================================
  500.  
  501. 3.1  Sybase ISQL
  502.  
  503. ---------------------------------------------------
  504. Question 3.1-1:  How do I prevent isql output from wrapping around at 80 
  505. columns?
  506.  
  507. Answer:    Use the -w switch.
  508.  
  509. ---------------------------------------------------
  510. Question 3.1-2:  How do I send isql output to a file? The -o switch 
  511. doesn't work.
  512.  
  513. Answer:    Use the redirection symbol, ">", as in 
  514.  
  515. isql -i script.sql > results.sql
  516.  
  517. ---------------------------------------------------
  518. Question 3.1-3:  Can I submit a multiline statement as input to isql 
  519. without creating a file with the commands in it first>
  520.  
  521. Answer:    Yes, try...
  522.  
  523. isql -Ulogin -Ppassword >outfile_name <<!
  524. use database
  525. go
  526. select column
  527. from table
  528. where condition is true
  529. order by column
  530.  
  531. go
  532. !
  533.  
  534. This is referenced as a "here document" in most UNIX manuals. This will 
  535. also result in the password being visible by anybody happening to do a 
  536. `ps' command when the command is run.
  537.  
  538. ---------------------------------------------------
  539. Question 3.1-4:  How do I prevent the password from being displayed when 
  540. someone does a UNIX *ps* command?
  541.  
  542. Answer:    Depending on the version of Sybase and the port, this may or 
  543. may not already be supported. In the cases where it is not supported, 
  544. several tricks have been used.
  545.  
  546. For those cases where the password shows up, try using the command line 
  547. options -i and -o rather than the shell redirects (< and >). This is 
  548. nice because the "Password:" prompt shows up to receive your input.
  549.  
  550. isql -U login -i input.sql -o output.out
  551. Password: password
  552.  
  553. You can also put the password as the first line that isql receives from 
  554. standard input.
  555.  
  556. isql -U logins >output.out <<EOT
  557. password
  558.  
  559. use database
  560. go
  561. sp_help
  562. go
  563. quit
  564. EOT
  565.  
  566. ---------------------------------------------------
  567. Question 3.1-5:  I want to add some new features to isql. Does anyone 
  568. have the source code?
  569.  
  570. Answer:    David Joyner at NCSU has published a shareware version, 
  571. called "dsql". It is available via anonymous ftp from 
  572. straylight.acs.ncsu.edu:/pub/sybase
  573.  
  574. ======================================================================
  575.  
  576. 3.2  Sybase Transact-SQL
  577.  
  578. ---------------------------------------------------
  579. Question 3.2-1:  What exactly does sp_primarykey, sp_foreignkey, and 
  580. sp_commonkey do?
  581.  
  582. Answer:    They register the key relationships in syskeys. They DON'T 
  583. create indexes and they DON'T make Sybase automatically enforce 
  584. referential integrity. the key relationships registered in syskeys may 
  585. be used by a front-end product to infer the logical schema.
  586.  
  587. ---------------------------------------------------
  588. Question 3.2-2:  I want to write a new system stored procedure that 
  589. gives me information not provided by the existing stored procedures. How 
  590. do I make these available to all users like the provided stored 
  591. procedures.
  592.  
  593. Answer:    All system stored procedures MUST start with the prefix 
  594. `sp_'. Procedures starting with this prefix have two main properties (1) 
  595. They are visible from all databases, and (2) They switch context to the 
  596. local database when executed. For example, a reference to the sysusers 
  597. table does not read from the master database, but from the local 
  598. database.
  599.  
  600. Do NOT replace any of the existing stored procedures with procedures of 
  601. your own design. Any upgrade which runs the `installmaster' script will 
  602. delete and overwrite your change.
  603.  
  604. ---------------------------------------------------
  605. Question 3.2-3:  How can I do a "row level select" (built-in "if" 
  606. function) without having to create a temporary table, etc.?
  607.  
  608. Answer:    This is a hint from langdont@penny.fir.london (Tony Langdon 
  609. FISD), found in SQL Forum magazine:
  610.  
  611. I'm trying to create a view on a table selecting one oftwo fields 
  612. depending on the value of a third e.g...
  613.  
  614. select field1 from table where field3 = 1
  615. union
  616. select field2 from table where field3 = 2
  617.  
  618. If field1 & field2 are integers then this will work
  619.  
  620. SELECT ISNULL( field1 / (1 - ABS (SIGN (field3 - 1))), ISNULL( 
  621. field2 / (1 - ABS( SIGN( field3 - 2))), <other value>))
  622. FROM table
  623.  
  624. The function (1 - ABS( SIGN(x - y))) is fuction which will return 1 
  625. if x = y and 0 otherwise. Division by zero returns NULL hence the 
  626. argument to the ISNULL function is returned.
  627.  
  628. Denoting (1 - ABS( SIGN(x - y))) as eqfn(x,y).
  629.  
  630. The solution where the fields are characters is more complicated.
  631.  
  632. SELECT SUBSTRING(field1 + field2,
  633. ISNULL(1 / eqfn( field3, 1), datalength(field1) + 1),
  634. ISNULL( datalength( field1 ) / eqfn( field3, 1 ), datalength( field2 )))
  635. FROM table
  636.  
  637. only this will return field1 if field3 is 1 and field2 otherwise. It 
  638. can be modified to return a different value if field3 is not 1 or 2.
  639.  
  640. Allthough this uses division by zero to get a NULL value and an 
  641. error will be displayed in SQL, this does not affect the results of 
  642. the query.
  643.  
  644. To the best of my knowledge it does not set @@error and the division 
  645. by zero error is returned, to an open client app, as if it was an SQL 
  646. print statement.
  647.  
  648. ---------------------------------------------------
  649. Question 3.2-4:  How do I use a table name as a parameter to a stored 
  650. procedure, which will then run a query on the specified table?
  651.  
  652. Answer:    You can't; also you can't do "dynamic queries". However, you 
  653. might want to try using sp_rename to "fool" Sybase, as suggested 
  654. (although not wholeheartedly recommended) by 
  655. rthomas@hakatac.almanac.bc.ca (Robert N Thomas) [this won't work with 
  656. temporary tables, though]:
  657.  
  658. 1.  Create a view of each table you will want to access as a 
  659. parameter.(this will allow other sessions to continue accessesing the 
  660. tables without interruption).
  661.  
  662. 2.  Set the permissions on the views so that NOBODY can access them. 
  663. Only through the MAGIC stored procedure is access granted to the views.
  664.  
  665. 3.  Figure out how to declare a section of your stored procedure as 
  666. critical, so that only one sybase process can access the below code at 
  667. one time.
  668.  
  669. 4.  Setup the procedure to look something like:
  670.  
  671.  CRITICAL (I forget the exact command).
  672.  sp_rename inuse, @vartable
  673.  select * from inuse
  674.  sp_rename @vartable, inuse
  675.  END CRITICAL portion
  676.  
  677. ---------------------------------------------------
  678. Question 3.2-5:  Can you change the definition of a table to prohibit 
  679. nulls once you've defined it to permit them?
  680.  
  681. Answer:    No, but you can prevent NULLs using triggers. A trigger can 
  682. use the `IS NULL' test to check if any column has a NULL value. A RULE 
  683. will not work. The rule check is not executed against columns that 
  684. contain a NULL value.
  685.  
  686. ---------------------------------------------------
  687. Question 3.2-6:  Is there a simple way to solve the Sybase ""matching 
  688. quotes"" requirement in a character field?
  689.  
  690. Answer:    An application program can use the dbsafestr() call, which is 
  691. part of DB-Library. This routine will double any and all quotes in a 
  692. character string, making that string "safe" for inclusion within any SQL 
  693. statement.
  694.  
  695. ---------------------------------------------------
  696. Question 3.2-7:  How can I do a case-insensitive search?
  697.  
  698. Answer:    [Was there ever an answer to this one?]
  699.  
  700. ---------------------------------------------------
  701. Question 3.2-8:  How do wildcards used for pattern matching work in the 
  702. context of the LIKE operator.
  703.  
  704. Answer:    This question is best answered with an example:
  705.  
  706. Given that table1 contains col1 and has the values
  707.  
  708. table1
  709. ----------
  710. Bob
  711. Ricky
  712.  
  713. The following query:
  714.  
  715. select * 
  716. from table1 
  717. where col1 not like '____'
  718. will return "Ricky" and will NOT return "Bob", "Ricky"
  719.  
  720. Here's why:
  721.  
  722. 1.  ["Bob" = "Bob "] is TRUE. This is a given, since ANSI says that in 
  723. comparing two strings, the shorter string will be conceptually padded 
  724. with blanks to equal the length of the longer string before comparing.
  725.  
  726. 2.  If 1 is TRUE, then ["Bob" LIKE "Bob "] is also TRUE. Otherwise, a 
  727. LIKE comparison would differ fundamentally from an EQUAL comparison.
  728.  
  729. 3.  ["Bob" LIKE "___"] and [" " LIKE "_"] are both TRUE, by Sybase's 
  730. definitions of the wildcards.
  731.  
  732. 4.  By 2 and 3, ["Bob" LIKE "Bob_"] is TRUE.
  733.  
  734. Therefore, ["Bob" LIKE "____"] is TRUE, and ["Bob" NOT LIKE "____"] is 
  735. FALSE. The query should NOT return "Bob", because the string has been 
  736. extended with blanks to pad it out to the length of the "longer" 
  737. (pattern) string.
  738.  
  739. To select all names of NOT EXACTLY 4 characters, use
  740.  
  741.  NOT LIKE "[^ ][^ ][^ ][^ ]"
  742.  
  743. This pattern string will match ONLY non-blank characters, so the query 
  744. will fail to match all strings with blanks in them ("Bob ") as well as 
  745. all strings longer than 4 characters ("Ricky").
  746.  
  747.  -- Elton Wildermuth, Sybase SQL Server Development
  748.  
  749. ---------------------------------------------------
  750. Question 3.2-9:  How do I put a unique serial number on a table?
  751.  
  752. Answer:    michael.keirnan@sybase.com (Michael Keirnan) writes:
  753.  
  754.     Create a reference table . . . with one row (I've also heard them 
  755. referred to as surrogate id tables). Create a stored procedure called 
  756. something like get_next_id. This stored procedure increments the current 
  757. id and returns, via a parameter, the new id. This of course is done 
  758. inside a transaction, and the increment (UPDATE statement) should be 
  759. done first. No trigger required. For example:
  760.  
  761. create table ID
  762. (NextId int)
  763. go
  764.  
  765. create procedure GetNextId
  766. @SurrogateId int out
  767. as
  768.     /* Start a transaction */
  769.     begin transaction
  770.  
  771.     /* Update the ID first to lock the table 
  772.     ** and block others from changing the value.
  773.     */
  774.     update ID
  775.     set NextId = NextId + 1
  776.  
  777.     /* Safe to select, others calls blocked. */
  778.     select @SurrogateId = NextId
  779.     from ID
  780.  
  781.     /* Commit the completed transaction */
  782.     commit transaction
  783. go
  784.  
  785. There is an important disclaimer to this method. This approach 
  786. guarantees that all inserts into the table are single threaded and that 
  787. concurrent inserts will never happen. Each request for an ID will be 
  788. blocked and wait for any preceeding requests for an ID since the page 
  789. containing the ID is locked. This could be a bottleneck for a multi-user 
  790. system.
  791.  
  792. ---------------------------------------------------
  793. Question 3.2-10:  Is it possible to explicitly lock a table in Sybase to 
  794. prevent other users from inserting into the table for a very short time?
  795.  
  796. Answer:    So far, the best solution that I have come across was 
  797. supplied by Scott Elliott of AT&T Network Systems. I have implemented 
  798. his method and it works fine. Here is what needs to be done:
  799.  
  800. declare @id
  801. begin transaction
  802. if not exists (select * from table HOLDLOCK where id=@id)
  803. begin
  804.         insert into table values (@id,...)
  805.      .
  806.      .
  807.      .
  808. end
  809. commit transaction
  810.  
  811. If two users execute this at the same time, the following will happen:
  812.  
  813. User 1 and User 2 acquire shared locks on the table. They will each hold 
  814. these locks until the end of the transaction (thanks to the HOLDLOCK 
  815. keyword). User 1 will request an exclusive lock of the transactions. End 
  816. result: ONLY 1 USER HAS ADDED THE ROW.You should also include some code 
  817. to check the return value of the transaction to see if it was rolled 
  818. back due to deadlock. If so, repeat the request on the table in order to 
  819. insert the new row. He will be blocked because User 2 still holds a 
  820. shared lock! User 2 will now request an exclusive lock to insert a row 
  821. also. He is also blocked since User 1 still holds his shared lock. We 
  822. now have DEADLOCK!!!! Sybase will then choose a victim and abort one.
  823.  
  824. ---------------------------------------------------
  825. Question 3.2-11:  Exactly when does a trigger fire?
  826.  
  827. Answer:    A trigger will fire once per statement affecting the table 
  828. (insert, update, and/or delete), even if NO rows are affected. It fires 
  829. after the physical table has been modified. This gives rise to coding 
  830. like:
  831.  
  832. create trigger happy_trails 
  833. on the_range 
  834. for update
  835. as
  836.  
  837. define @rows_altered int
  838. select @rows_altered = count(*) from inserted
  839. if (@rows_altered = 0) return
  840. ...
  841.  
  842. This eliminates the expense of going through later trigger code which 
  843. will have no effect. A similar method can be used if, for example, you 
  844. want to allow only one row inserted per statement.
  845.  
  846. ---------------------------------------------------
  847. Question 3.2-12:  Is there an easy way within the server to determine 
  848. how many days are in the current month?
  849.  
  850. Answer:    This solution comes from Elton Wildermuth at Sybase
  851.  
  852. Obtain the month number, M.
  853. If (M = 2) /* February is a special case */
  854.  
  855.     Obtain the 4 digit year, Y
  856.     if    ((Y % 4 = 0) and
  857.         ((Y % 100 != 0) or
  858.         (Y % 400 = 0)))
  859.  
  860.         days := 29
  861.     else
  862.         days := 28
  863. else
  864.     if (M > 7) /* If month is after "July" */
  865.         M := M - 7 /* subtract 7 from month */
  866.  
  867.     days := 30 + (M & 1)
  868.  
  869.     /* Now, if month is odd, it has 31 days */
  870.  
  871. Why this works:
  872.  
  873.  31 30 31 30 31 30 31
  874.  Ja -- Ma Ap My Ju Jy
  875.  Au Se Oc No De
  876.  
  877. Suggestion: build this into a stored procedure, and call it; assign 
  878. its return value to a variable. Give the procedure an optional 
  879. datetime param, so that it can calculate days-in-month for a random 
  880. date; let the date default to getdate(). Example:
  881.  
  882. create procedure get_days
  883.     @days int OUTPUT,
  884.     @date datetime=NULL
  885. as
  886.  
  887. declare        @m int,
  888.         @y int
  889.  
  890. if (@date is NULL)
  891.     select @date = getdate()
  892.  
  893. select @m = datepart(mm, @date)
  894.  
  895. if (@m = 2)
  896. begin
  897.     select @y = datepart(yy, @date)
  898.     if    (@y % 4 = 0) and 
  899.         ((@y % 100 != 0) or    (@y % 400 = 0))
  900.         select @days = 29
  901.     else
  902.         select @days = 28
  903.     end
  904. else
  905. begin
  906.     if (@m > 7)
  907.         select @m = @m - 7
  908.     select @days = (30 + (@m & 1))
  909. end
  910. return
  911.  
  912.  
  913. ======================================================================
  914.  
  915. 3.3  Sybase Bulk Copy
  916.  
  917. ---------------------------------------------------
  918. Question 3.3-1:  When using BCP to copy a database, is the copy 
  919. equivalent to the original in terms of performance?
  920.  
  921. Answer:    Copying will remove the "holes" and compact the rows more 
  922. contiguously than the original so that the copy will perform 
  923. substantially better. bcp-ing into an empty table with indexes, or 
  924. building the indexes after the data is all in WILL indeed fill in the 
  925. gaps in the extent chains where rows had been deleted in the original 
  926. source table. Rows are always compacted to have no spaces between rows, 
  927. but pages can be right around half-full if many many deletes have taken 
  928. place all over the table space. The easy way to "even the score" is to 
  929. re-create the clustered index on the production table, if you can.
  930.  
  931. Unless you note a substantial difference between the reserved space 
  932. given by sp_spaceused for both tables, the performance difference is 
  933. typically not that great.
  934.  
  935. The best way to copy a database is to use DUMP DATABASE and LOAD 
  936. DATABASE... it's just one operation, and produces an exact page-by-page 
  937. copy of the original database, "spaces" and all.
  938.  
  939. Benjamin von Ullrich Benjamin.von.Ullrich@sybase.com
  940.  
  941. ---------------------------------------------------
  942. Question 3.3-2:  Can BCP load null dates?
  943.  
  944. Answer:    BCP can load null dates if there is nothing between the 
  945. delimiters for the columns. If it encounters a space it converts that to 
  946. Jan 1, 1900. Here is an example:
  947.  
  948. create table foo
  949.  (seq_no int not null,
  950.  date1 datetime null,
  951.  date2 datetime null)
  952.  
  953. The following is the contents of a file that we are going to bcp into 
  954. table foo. I am using a tilde to delimit columns and a tilde followed by 
  955. a return (\n) as a row terminator.
  956.  
  957. 1~ ~~
  958. 2~~ ~
  959. 3~~~
  960.  
  961. Now we use bcp with the delimiters specified above.
  962.  
  963. bcp foo in foo.dat -c -t~ -r"~\n"
  964.  
  965. Starting copy...
  966. 3 rows copied.
  967. Clock Time (ms.): total = 37 Avg = 12 (81.08 rows per sec.)
  968.  
  969. Via isql let's look at the results.
  970.  
  971. 1> select * from foo
  972. 2> go
  973.  
  974.  seq_no      date1                      date2
  975.  ----------- -------------------------- --------------------------
  976.  1           Jan 1 1900 12:00AM         NULL
  977.  2           NULL                       Jan 1 1900 12:00AM
  978.  3           NULL                       NULL
  979.  
  980. (3 rows affected)
  981.  
  982. ======================================================================
  983.  
  984. 3.4  Sybase Backup and Recovery
  985.  
  986. ---------------------------------------------------
  987. Question 3.4-1:  How can I dump more than one database to a single tape?
  988.  
  989. Answer:    Tell Sybase that the tape device is really a disk.Declare the 
  990. tape /dev/nrst? as a "disk" device (sp_addumpdevice "disk", ...). Then 
  991. successive dumps will follow each other on tape. Of course, you've got 
  992. to maintain your own directory of what's on the tape. Use the "mt -f /
  993. dev/nrst0 sta" to check. Or write your databases to files and write the 
  994. files to tape using standard unix commands.
  995.  
  996. Note that this is commonly practiced, BUT here is what one article 
  997. originating from Sybase stated...
  998.  
  999. Please save yourself a lot of grief and don't do this. The various 
  1000. platforms handle tapes in slightly different ways and the various Sybase 
  1001. server ports make slightly different attempts to work around this. On 
  1002. some platforms the above suggestion will work, but on some other 
  1003. platforms, you overwrite your dump, and on yet others, it just fails. 
  1004. Worse yet, from OS release to OS release, and Sybase release to Sybase 
  1005. release, the behavior of any specific platform can change.
  1006.  
  1007. The point of doing dumps is that you know your data is safe. If you are 
  1008. doing something that is "not really supported", then how do you know 
  1009. your data is safe? If you don't care if your data is safe, save even 
  1010. more tapes and don't do dumps at all.
  1011.  
  1012. None of the above is meant to imply that the Sybase dump mechanism is 
  1013. better or worse than any other possibility. However, it is the mechanism 
  1014. Sybase provides and supports. 
  1015.  
  1016. David Gould, dg@sybase.com
  1017.  
  1018. And one final word, Sybase System 10 includes a Backup Server, which 
  1019. will handle this problem.
  1020.  
  1021. ======================================================================
  1022.  
  1023. 3.5  Upgrading the Sybase Server
  1024.  
  1025. ---------------------------------------------------
  1026. Question 3.5-1:  I'm upgrading from version <x> and/or operating system 
  1027. <p> to version <y> and/or operating system <q>. Any advice?
  1028.  
  1029. Answer:    The answers vary from "No problem" to "You're doomed". Since 
  1030. this type of question comes up often, perhaps it should have a sub-FAQ?
  1031.  
  1032.  
  1033.  
  1034. ======================================================================
  1035.  
  1036. 3.6  Sybase Security
  1037.  
  1038. ---------------------------------------------------
  1039. Question 3.6-1:  What different mechanisms are there to control Sybase 
  1040. security?
  1041.  
  1042. Answer:    The following summarizes techniques to control security with 
  1043. SQL Server that I have received from various sources plus some comments 
  1044. of my own. My concern was how to control updates to a database in an 
  1045. environment with end-user "query"" tools that include update 
  1046. capabilities (e.g. Pioneer, Q+E, Microsoft Access). I want to especially 
  1047. thank those who responded to my question. All responses where useful.
  1048.  
  1049.        There are four fundamental methods, each described in more detail below: 
  1050. (1) adopted authority; (2) login ID; (3)gatekeeper; (4) triggers. All 
  1051. techniques are premised on fundamental security features of user 
  1052. authentication and grant/revoke permissions to resources. Each 
  1053. technique has a cost and must be weighed against the risk/benefit.
  1054.  
  1055.     Where available, references are cited. Particularly useful for those 
  1056. with access to CompuServe are Microsoft's Knowledge Base (MSKB) and 
  1057. Microsoft's Software Library (MSL).
  1058.  
  1059. 1.  Adopted authority.
  1060.  
  1061.     This seems to be the most common approach making use of SQL Servers 
  1062. authority checking structure -- if the owner of an object (stored 
  1063. procedure or view) has necessary authority to all underlying objects, 
  1064. then authorized users of this object have the same authority. All 
  1065. updates are done via stored procedures owned by a user with update 
  1066. authority to underlying objects. Users are granted authority to stored 
  1067. procedures but do not have update authority to any tables. As Michele 
  1068. Sherry wrote, ". . . encapsulate your database as much as possible using 
  1069. views and stored procedures."
  1070.  
  1071.     The assumption here is that users are not aware of stored procedures 
  1072. since they will only be used by application programs for database 
  1073. maintenance. It is possible to "hide" the stored procedures; possibly in 
  1074. a totally different database or see comment below by Robert Thomas. 
  1075. Still the knowledgeable user could find them and execute them. 
  1076. Programmers might object to the use of stored procedures versus direct 
  1077. use of SQL.
  1078.  
  1079.     In the case where applications are written using end-user tools such as 
  1080. Q+E and Excel, Robert Thomas describes hiding the calls to stored 
  1081. procedures using DDE or DLL calls; possibly using a special password as 
  1082. a parameter to the stored procedure. He also recommends making sure 
  1083. sp_helptext for these procedures return nothing. He sometimes uses a 
  1084. technique of mixing DDE and DLL calls in which in the middle of a DDE 
  1085. conversation he establishes a temporary second login to SQL Server for 
  1086. update purposes using DLL calls.
  1087.  
  1088.     See MSKB article Q47270: "INF: SQL Access Permissions and Trigger 
  1089. Execution" which describes SQL Server adopted authority structure using 
  1090. triggers. However, this concept applies as well to stored procedures and 
  1091. views.
  1092.  
  1093. 2.  Login IDs
  1094.  
  1095.     The basic idea is to use different login IDs for update and query use. 
  1096. The trick is to keep the one for update hidden and unobtrusive. There 
  1097. are several techniques for doing this with varying degrees of 
  1098. sophistication.
  1099.  
  1100.     Maintenance applications could use a single special ID and password that
  1101. allows update privileges; while normal user IDs have read only 
  1102. authority. This is based on the assumption that access to applications 
  1103. is controlled and that steps are taken to make sure the special login 
  1104. does not become common knowledge. One problem is that it is difficult to 
  1105. tell who is logged onto the database since they all use the same ID.
  1106.  
  1107.     Lawrence Bertolini wrote with a table driven variation of the above. A 
  1108. special login is used by an application to access, of course, a special 
  1109. table. This table cross references a normal login ID to a special login 
  1110. ID. Once the special ID is located, the application logoffs and then 
  1111. back on using the special ID. For example, my normal ID might be "seth" 
  1112. but my special ID might be"seth_12x9t". Again, normal precautions must 
  1113. be taken to ensure that this scheme is not compromised.
  1114.  
  1115. 3.  Gatekeeper
  1116.  
  1117.     The most sophisticated approach is to control all logins with a custom 
  1118. written front-end gatekeeper to SQL Server. All requests to SQL Server 
  1119. must pass through this program which can determine the privileges needed 
  1120. by the requester. The action taken by the program is flexible. Two 
  1121. possibilities are to use the two login ID approach as above or to 
  1122. analyze each request rejecting those that are not acceptable (e.g. 
  1123. update from Q+E). This approach also allows maintaining an audit trail 
  1124. of SQL Server logins and requests. The key issue is authenticating the 
  1125. requesting program. The login ID can be authenticated using the native 
  1126. operating system security.
  1127.  
  1128.     This technique is described in Microsoft's "Open Data Services User's 
  1129. Guide" as the SECURE application. Manual and source are included with 
  1130. SQL Server 4.2. It is also described in MSKB article Q79958: "INF: ODS 
  1131. Security and Auditing Application". Source for SECURE42 should be in MSL 
  1132. as "S13264" however it is missing as of this writing but I am told it 
  1133. will be added within a week or two. This program requires Microsoft's 
  1134. SQL Server Programmer's Reference for C.
  1135.  
  1136. 4.  Triggers
  1137.  
  1138.     This technique places update control logic inside triggers associated 
  1139. with each table. For example, the trigger could check a table to make 
  1140. sure the requesting application was authorized for updates. This 
  1141. technique is described in MSKB article Q66678: "INF: Providing 
  1142. Application Security Through Triggers in SQL". Obviously a trigger needs 
  1143. to be written for each table however the update check could be placed in 
  1144. its own stored procedure and work for all tables.
  1145.  
  1146. 5.  Other ideas
  1147.  
  1148.     Possibly an obvious answer: don't provide tools for ad hoc queries that 
  1149. include update capabilities. It seems in the personal computer arena 
  1150. this is unrealistic.
  1151.  
  1152.     Another option is physically separate database for update and ad hoc 
  1153. query. There is a fair amount of overhead but actually might work well 
  1154. where performance is critical for maintenance transactions.
  1155.  
  1156. Disclaimer:
  1157.  
  1158.     I have tried to present the above information as accurately as possible 
  1159. including citations. However, I leave it up to you to verify the 
  1160. information and determine its correctness and applicability to your 
  1161. needs.
  1162.  
  1163. Provided by: Seth Siegal, ssiegal@hebron.connected.com
  1164.  
  1165. ======================================================================
  1166.  
  1167. 3.7  Sybase Database Administration
  1168.  
  1169. ---------------------------------------------------
  1170. Question 3.7-1:  Why does the transaction log on the model database keep 
  1171. filling up?
  1172.  
  1173. Answer:    Up to release 4.8, SQL server stored tempdb's next object_id 
  1174. in the log of the model database.I don't remember exactly why this was 
  1175. necessary, but i think it has something to do with avoiding re-issuance 
  1176. of object_ids that may be in stored procedures and/or transaction logs 
  1177. of all server databases. Since model is copied into tempdb at boot time, 
  1178. it seemed logical to store the next object id in model. All that was 
  1179. logged was a 4-byte integer, so it could take months for the log in 
  1180. model to fill up. This problem was fixed in version 4.8 . The next 
  1181. object id is now stored elsewhere.
  1182.  
  1183. ---------------------------------------------------
  1184. Question 3.7-2:  Why does my transaction log fill up even when I have 
  1185. allocated lots of space for it?
  1186.  
  1187. Answer:    Due to the sequential nature of the log, only the inactive 
  1188. portion of the log may be truncated by any DUMP TRANSACTION command. The 
  1189. inactive portion of the log runs from the "beginning" to the page which 
  1190. has the BEGIN XACT record for the oldest *active* (uncommitted) 
  1191. transaction. Pages which follow this oldest active transaction in the 
  1192. log are considered active for the purposes of DUMP TRANSACTION, since 
  1193. they may depend on changes made (yet to be committed or still to be 
  1194. rolled back) by this transaction. Recovery (at LOAD TRAN or system 
  1195. startup time) replays transactions as committed or rolled back in the 
  1196. exact order in which they appear in the log, so portions appearing in 
  1197. the log after an uncommitted transaction may not be removed.
  1198.  
  1199. The implication here is that given a large enough or long-running enough 
  1200. transaction, one can hold up the entire log (from dumping, not from 
  1201. continued logging!) while the transaction is still pending. If your log 
  1202. fills up, and you have a very old transaction that started at the 
  1203. beginning of the log, no DUMP TRAN command can or will clear it until 
  1204. the transaction COMMITs or is ROLLed BACK.
  1205.  
  1206. The only things you can do in this case are:
  1207.  
  1208. 1.  ALTER DATABASE to add more space to the log, hopefully allowing 
  1209. enough space & time for your old transaction(s) to commit (find that 
  1210. user who typed BEGIN TRAN ... UPDATE/INSERT/DELETE ... and the went to 
  1211. lunch!). KILL the long-running process/transaction.
  1212.  
  1213. 2.  Shut down the sql server to terminate the long-running/old 
  1214. transaction.
  1215.  
  1216. These last two effectively terminate the transaction without a COMMIT, 
  1217. making it get rolled back upon recovery. This is a fairly drastic action 
  1218. to kill a process to clear a log.... if you can issue a COMMIT TRAN in 
  1219. the open session, or type ^C to abort from the same, please do so to 
  1220. achieve a cleaner and easier return to normal processing. 
  1221.  
  1222. Long-term, it is best to avoid long/log-intensive transactions. To begin 
  1223. with, break up large deletes into smaller parts by adding a where 
  1224. clause. This advice on use of a WHERE clause to break up DELETEs into 
  1225. chunks applies the same to UPDATEs, and similarly for INSERT.
  1226.  
  1227. If your problem transaction is to delete all rows in a table, consider 
  1228. using the TRUNCATE TABLE command. This command uses a minuscule 
  1229. proportion of log vs.a DELETE of all rows, as it merely logs the 
  1230. deallocation of pages for the table, not the image of every row deleted. 
  1231. For this reason, it is also MUCH faster than DELETE for most good-sized 
  1232. tables.
  1233.  
  1234. Benjamin von Ullrich, ben@sybase.com
  1235.  
  1236. ---------------------------------------------------
  1237. Question 3.7-3:  Is there a way to trun off logging altogether? How 
  1238. about putting the transaction logs on `/dev/null'? How does tempdb avoid 
  1239. logging?
  1240.  
  1241. Answer:    The transaction logs are an integral part of Sybase 
  1242. operations. It must be able to read from as well as write to the log 
  1243. device. This is why /dev/null won't work. 
  1244.  
  1245. What you can do is use `sp_changedboption dbname, trunc, true' to set 
  1246. the truncate log on checkpoint option to true. This will automatically 
  1247. clear out the log every minute or so. This is how tempdb works. Keep in 
  1248. mind that you have just prevented recovery from incremental transaction 
  1249. log dumps (dump tran) and that you can ONLY recover the database from 
  1250. the last full database backup (dump database).
  1251.  
  1252. ---------------------------------------------------
  1253. Question 3.7-4:  Is there any reason not to have `truncate log on 
  1254. checkpoint' turned on for the model database?
  1255.  
  1256. Answer:    Since this database is the template for all databases at 
  1257. CREATE DATABASE time, setting this option on in model makes it be 
  1258. automatically set on for all new databases as they are created. Aside 
  1259. fro the simple fact that this may not be what you want on all new 
  1260. databases, if you are in the midst of a frenzied recovery of a major 
  1261. production database (say, in the middle of the day, while all your users 
  1262. are down), and you load your database backup, the first gift your clever 
  1263. option on model will give you is a truncated log in front of all of the 
  1264. transaction log dumps you were about to apply to bring the database you 
  1265. just loaded up to the time of failure. Truncating the log at any time 
  1266. between LOAD DATABASE and your last LOAD TRANSACTION blasts a hole in 
  1267. the log chain and halts the recovery operation then and there.
  1268.  
  1269. ---------------------------------------------------
  1270. Question 3.7-5:  Why doesn't the Sybase kill command work?
  1271.  
  1272. Answer:    Killing a Sybase process will result in one of four 
  1273. reactions:
  1274.  
  1275. 1.  The process is an ordinary retrieve transaction, i.e. SELECT, and it 
  1276. dies immediately.
  1277.  
  1278. 2.  The process is an update transaction. It does not die until the 
  1279. server has rolled back the transaction. The time is directly related to 
  1280. the size of the transaction.
  1281.  
  1282. 3.  The process is a DBCC transaction. Sybase forks a separate process 
  1283. for the transaction, and the new one is out of the users' control. DBCC 
  1284. checks tables index by index and can only be killed when it finishes one 
  1285. index and is ready for the next one. It may take anywhere from several 
  1286. minutes to four hours to die.
  1287.  
  1288. 4.  The process is sleeping. We cannot kill a sleeping process. When an 
  1289. end-user process gets disconnected, we cannot kill the Sybase process 
  1290. and release the locks. To deal with this, we have installed an EBF 
  1291. (ebf989 for version 4.8 on Vax/VMS) to kill disconnected processes when 
  1292. our clients turn off thir PCs. Sybase claims that System 10 will provide 
  1293. an unconditional kill
  1294.  
  1295. ---------------------------------------------------
  1296. Question 3.7-6:  What are some of the undocumented features of DBCC?
  1297.  
  1298. Answer:    There are a number of undocumented DBCC options that tech 
  1299. support uses to analyze your database. Some of these are DESTRUCTIVE and 
  1300. tech support will not help you if you screw up your database using one 
  1301. of these commands. They can also tell what you have done. With that in 
  1302. mind, here is a summary of the DBCC commands:
  1303.  
  1304. Stay tuned, summary will follow in next release.
  1305.  
  1306. ---------------------------------------------------
  1307. Question 3.7-7:  What are the trace flags used for and what are some of 
  1308. the more common flags.
  1309.  
  1310. Answer:    There are a number of trace flags that can be used.  An 
  1311. initial list follows:
  1312.  
  1313. dbcc traceon(3604)  redirects dbcc output to your screen rather than 
  1314. the console.
  1315.  
  1316. dbcc traceon(3605)  redirects dbcc output to the errorlog.
  1317.  
  1318. ---------------------------------------------------
  1319. Question 3.7-8:  Is there a way to accurately estimate how much space a 
  1320. table and its indeces are going to take?
  1321.  
  1322. Answer:    FYI, lot's of people have asked for it, and here it is! the 
  1323. officially UNSUPPORTED stored procedure sp_estspace. It works under 
  1324. 4.9.2, but I make no guarantees. What's it good for: estimating the size 
  1325. of tables and their indexes given an existing table and index schema.
  1326.  
  1327. Have fun.
  1328.  
  1329. **************************************************
  1330. Doug Smith Sr. Instructor
  1331. Sybase Professional Services, Northwest District
  1332. dougs@sybase.com
  1333. ***************************************************
  1334.  
  1335. create procedure sp_estspace
  1336. /*    A procedure to estimate the disk space requirements of a table
  1337. **    and its associated indexes.
  1338. **    November 21, 1991
  1339. **    Written by Malcolm Colton with assistance from Hal Spitz
  1340. **    Modified by Jim Panttaja November 25, 1991
  1341. */
  1342.  
  1343.     (@table_name    varchar(30)=null, /* name of table to estimate */
  1344.      @no_of_rows    float = 1,     /* number of rows in the table */
  1345.      @fill_factor    float = 0,    /* the fill factor */
  1346.      @cols_to_max    varchar(255) =null /* variable length columns for 
  1347.                                               which to use the maximum rather 
  1348.                                               than 50% of the maximum length */
  1349.      )
  1350. as
  1351.  
  1352. declare @msg    varchar(120)
  1353.  
  1354. /*    Give usage statement if @table_name is null */
  1355. if @table_name = null or @no_of_rows = 1
  1356. begin
  1357.     print `Usage is:'
  1358.     print ` estspace table_name, no_of_rows, fill_factor, cols_to_max'
  1359.     print `where table_name is the name of the table,'
  1360.     print ` no_of_rows is the number of rows in the table,' 
  1361.     print ` fill_factor is the index fill factor (default = 0) ` 
  1362.     print ` cols_to_max is a list of the variable length columns for which'
  1363.     print ` to use the maximum length instead of the average'
  1364.     print `             (default = null)'
  1365.     print `Examples: estspace titles, 10000, 50, "title, notes"'
  1366.     print ` estspace titles, 50000'
  1367.     print ` estspace titles, 50000, 0, null, 40'
  1368.  
  1369.     return
  1370. end
  1371.  
  1372. declare    @sum_fixed    int,
  1373.     @sum_var    int,
  1374.     @sum_avgvar    int,
  1375.     @table_id    int,
  1376.     @num_var    int,
  1377.     @data_pages    float,
  1378.     @sysstat    tinyint,
  1379.     @temp        float,
  1380.     @index_id    int,
  1381.     @last_id    int,
  1382.     @i        int,
  1383.     @level_pages    float,
  1384.     @key        varchar(30),
  1385.     @usertype    tinyint,
  1386.     @type        tinyint,
  1387.     @level        tinyint,
  1388.     @vartype    smallint,
  1389.     @more        bit,
  1390.     @next_level    float,
  1391.     @rows_per_page    smallint,
  1392.     @row_len    smallint,
  1393.     @length        tinyint,
  1394.     @index_name    varchar(30),
  1395.     @page_size    smallint,
  1396.     @page_K        tinyint,
  1397.     @index_type    varchar(20),
  1398.     @factor        float
  1399.  
  1400. select    @sum_fixed=0,
  1401.     @sum_var=0,
  1402.     @sum_avgvar=0,    
  1403.     @table_id=0,
  1404.     @num_var=0,
  1405.     @data_pages=0,
  1406.     @row_len=0,
  1407.     @sysstat=0
  1408.  
  1409. set nocount on
  1410.  
  1411. /* Make sure table exists */
  1412. select @sysstat = sysstat,
  1413.     @table_id = id
  1414.         from sysobjects where name = @table_name
  1415.         and uid = user_id()
  1416.  
  1417. if @sysstat & 7 not in (1,3)
  1418. begin
  1419.     select @msg = "I can't find the table "+@table_name
  1420.     print @msg
  1421.  
  1422.     return
  1423. end
  1424.  
  1425. /* Get machine page size */
  1426. select     @page_size = low - 32
  1427.     from master.dbo.spt_values
  1428.         where type = `E'
  1429.         and number = 1
  1430.  
  1431. select @page_K = (@page_size +32) /1024
  1432.  
  1433. if @fill_factor !=0
  1434.     select @fill_factor = @fill_factor / 100.0
  1435.  
  1436. /* Create tables for results */
  1437. create table #results
  1438.     (name    varchar(30),
  1439.      type    varchar(12),
  1440.      level    tinyint,
  1441.      pages    float,
  1442.      Kbytes float)
  1443.  
  1444. create table #times
  1445.     (name         varchar(30),
  1446.      type         varchar(12) null,
  1447.      tot_pages    float,
  1448.      time_mins    float     null)
  1449.  
  1450. /* Create table of column info for the table to be estimated */ 
  1451. select length, type, name, offset
  1452.     into #col_table
  1453.         from syscolumns
  1454.             where id = @table_id
  1455.  
  1456. /* Look up the important values from this table */
  1457. select @sum_fixed = isnull(sum(length),0)
  1458.     from #col_table
  1459.         where offset !< 0
  1460.  
  1461. select @num_var = isnull(count(*),0), 
  1462.        @sum_var = isnull(sum(length),0)
  1463.     from #col_table
  1464.         where offset < 0
  1465.             and charindex(name, @cols_to_max) > 0
  1466.  
  1467. select @num_var = @num_var + isnull(count(*),0), 
  1468.        @sum_avgvar = isnull(sum(length / 2),0)
  1469.     from #col_table
  1470.         where offset < 0
  1471.             and charindex(name, @cols_to_max) = 0
  1472.  
  1473. /* Calculate the data page requirements */
  1474. if @num_var = 0
  1475.     select @row_len = 4.0 + @sum_fixed
  1476. else
  1477.     select @row_len = 8.0 + @sum_fixed + @sum_var +@sum_avgvar + @num_var
  1478.                 + (@sum_var +@sum_avgvar) / 256.0
  1479.  
  1480. /* Allow for fill-factor if set to other than zero */
  1481. if @fill_factor = 0    
  1482.     select @temp = convert(float, @no_of_rows) * 
  1483.         ( convert(float, @row_len) / convert(float, @page_size) )
  1484. else
  1485. begin
  1486.     select @temp = convert(float, @no_of_rows) / 
  1487.         (convert(float, @page_size) * convert(float, @fill_factor) )
  1488.  
  1489.     select @temp = convert(float, @row_len) * @temp
  1490. end
  1491.  
  1492. /* Now add in allocation pages */
  1493. select @temp = @temp +(@temp / 256.0)
  1494.  
  1495. select @data_pages = @temp + 1.0
  1496.  
  1497. if @data_pages < 8.0
  1498.     select @data_pages = 8.0
  1499.  
  1500. insert #results values 
  1501.     (@table_name, `data', 0, @data_pages, @data_pages * @page_K)
  1502.  
  1503. /* See if the table has any indexes */
  1504. select @index_id = min(indid)
  1505.     from sysindexes 
  1506.         where id = @table_id
  1507.             and indid > 0
  1508. if @index_id = null    /* We've finished if there are no indexes */
  1509. begin
  1510.     select @msg = @table_name + ` has no indexes'
  1511.     print @msg
  1512.  
  1513.     select name, type, level, 
  1514.         Pages = str(pages,12,0), Kbytes = str(Kbytes,12,0) 
  1515.         from #results
  1516.  
  1517.     select Total_Mbytes = str(sum(Kbytes)/1000.0,15,0)
  1518.         from #results
  1519.  
  1520.     drop table #results
  1521.  
  1522.     return
  1523. end
  1524.  
  1525. select     @sum_fixed = 0,
  1526.     @sum_var = 0,
  1527.     @num_var = 0,
  1528.     @temp = 0
  1529. /* For each index, calculate the important variables
  1530. ** use them to calculate the index size, and print it */
  1531. while @index_id != null
  1532. begin
  1533.     select @index_name = name 
  1534.         from sysindexes
  1535.             where id = @table_id
  1536.             and indid = @index_id
  1537.  
  1538.     if @index_id = 1
  1539.         select @index_type = `clustered'
  1540.     else
  1541.         select @index_type = `nonclustered'
  1542.  
  1543.     select     @num_var = 0,
  1544.         @sum_var = 0,
  1545.         @sum_fixed = 0
  1546.  
  1547.     select @i = 1
  1548.  
  1549.     /* Look up each of the key fields for the index */
  1550.     while @i <= 16
  1551.     begin
  1552.         select @key = index_col(@table_name, @index_id, @i)
  1553.         if @key = null
  1554.             break
  1555.         else            /* Process one key field */
  1556.         begin
  1557.             select @type = type, @length = length, @vartype = offset
  1558.                 from syscolumns
  1559.                     where id = @table_id
  1560.                     and name = @key
  1561.  
  1562.             if @vartype < 0
  1563.                 select @num_var = @num_var + 1
  1564.             else
  1565.                 select @sum_fixed = @sum_fixed + @length
  1566.  
  1567.             if @vartype < 0    /* variable:check if in @cols_to_max */ 
  1568.             begin
  1569.                 if charindex(@key, @cols_to_max) = 0
  1570.                  select @sum_var = @sum_var + (@length / 2)
  1571.                 else
  1572.                  select @sum_var = @sum_var + @length
  1573.             end
  1574.         end
  1575.  
  1576.         select @i = @i + 1    /* Get next key field in this index */
  1577.     end
  1578.  
  1579.     /* Calculate the space used by this index */
  1580.     if @num_var = 0
  1581.         select @row_len = 5 + @sum_fixed
  1582.     else
  1583.         select @row_len = @sum_fixed + @sum_var + @num_var + 8
  1584.  
  1585.     if @index_id != 1    /* add row id for nc indexes */
  1586.         select @row_len = @row_len + 4
  1587.  
  1588.     select @level = 0
  1589.  
  1590.     /* Allow for fill-factor if set to other than zero */
  1591.     if @fill_factor = 0    
  1592.         select @rows_per_page = @page_size / @row_len - 2
  1593.     else
  1594.         select @rows_per_page = @page_size / @row_len * @fill_factor 
  1595.  
  1596.     if @rows_per_page > 256
  1597.         select @rows_per_page = 256
  1598.  
  1599.     /* For clustered indexes, the first level of index is based on the 
  1600.     ** number of data pages. 
  1601.     ** For nonclustered, it is the number of data rows    */
  1602.     if @index_id = 1
  1603.         select @next_level = @data_pages
  1604.     else
  1605.         select @next_level = @no_of_rows
  1606.  
  1607.     select @more = 1    /* Flag for end of index levels */
  1608.     while @more = 1
  1609.     begin
  1610.         /* calculate the number of pages at a single index level */
  1611.         select @temp = @next_level / convert(float, @rows_per_page)
  1612.  
  1613.         /* Add in a factor for allocation pages */
  1614.         if @temp > 200.0
  1615.             select @temp = @temp + (@temp /256.0) + 1.0
  1616.  
  1617.         select @level_pages = @temp
  1618.  
  1619.         insert #results values
  1620.             (@index_name, @index_type, @level, @level_pages, 
  1621.                 @level_pages * @page_K)
  1622.  
  1623.         if @index_id != 1 and @level = 0 /* adjust NC non-leaf rows */ 
  1624.         begin
  1625.             select @row_len = @row_len + 4 
  1626.  
  1627.             /* Allow for fill-factor if set to other than zero */
  1628.             if @fill_factor = 0    
  1629.                 select @rows_per_page = @page_size/@row_len - 2
  1630.             else
  1631.                 select @rows_per_page = @page_size/
  1632.                                        @row_len*@fill_factor
  1633.             end
  1634.  
  1635.         if @rows_per_page > 256
  1636.             select @rows_per_page = 256
  1637.  
  1638.         select @next_level = @level_pages
  1639.  
  1640.         select @level = @level + 1
  1641.  
  1642.         /* see if we can fit the next level in 1 page */
  1643.         if @rows_per_page >= @next_level 
  1644.             select @more = 0
  1645.     end
  1646.  
  1647.     /* Account for single root page */
  1648.     if @level_pages > 1
  1649.         insert #results values
  1650.             (@index_name, @index_type, @level, 1, @page_K)
  1651.  
  1652.     /* Now look for next index id for this table */
  1653.     select @last_id = @index_id
  1654.  
  1655.     select @index_id = null
  1656.  
  1657.     select @index_id = min(indid)
  1658.         from sysindexes 
  1659.             where id = @table_id
  1660.             and indid > @last_id
  1661. end
  1662.  
  1663. select name, type, level, Pages = str(pages,12,0), Kbytes = str(Kbytes,12,0) 
  1664. from #results
  1665.  
  1666. select Total_Mbytes = str(sum(Kbytes)/1000.0,15,0)
  1667. from #results
  1668.  
  1669. drop table #results
  1670.  
  1671. drop table #col_table
  1672.  
  1673. return
  1674.  
  1675.  
  1676. ---------------------------------------------------
  1677. Question 3.7-9:  Can I recover a database that comes up marked 
  1678. `SUSPECT'?
  1679.  
  1680. Answer:    Assuming that you have got a backup of the database files or 
  1681. partitions!!!!
  1682.  
  1683. 1.  start the dataserver. watch the database come up "suspect"
  1684. 2.  execute isql as "sa"
  1685.  > sp_configure "allow",1
  1686.  > go
  1687.  > reconfigure with override
  1688.  > go
  1689.  > update master..sysdatabases set status = -32768 
  1690.          where name='<suspect_db_name>'
  1691.  > go
  1692.  > use <suspect_db_name>
  1693.  > go (to verify that you can actually open the database!)
  1694.  > use master
  1695.  > go
  1696.  > dbcc save_rebuild_log (<suspect_db_name>)
  1697.  > go
  1698.  
  1699. * note: the above should recreate your destroyed transaction log. The 
  1700. setting of status=-32768 in master..sysdatabases means "bypass 
  1701. recovery", causing SQL server to ignore all of the conditions which are 
  1702. causing your database to come up suspect. 
  1703.  
  1704. Do not try this at home without a backup.
  1705.  
  1706.  > update master..sysdatabases set status=0
  1707.       where name='<suspect_db_name>'
  1708.  > go
  1709.  > sp_configure "allow",0
  1710.  > go
  1711.  > reconfigure
  1712.  > go
  1713.  > shutdown
  1714.  
  1715. 3.  try to restart the SQL Server. watch to see if the database comes up 
  1716. OK. if it does, you dodged a bullet. count your blessings and take a 
  1717. database dump next time.
  1718.  
  1719. Lee McGee lmcgee@sgi.com
  1720.  
  1721. ---------------------------------------------------
  1722. Question 3.7-10:  My database tables often get locked by the client's 
  1723. hung workstation. Is there a way that I can unlock those locked tables?
  1724.  
  1725. Answer:    The most common reasons for this kind of behavior is a PC 
  1726. client where the user in the middle of the query assumes he has had 
  1727. enough and reboots the PC. This will leave a sleeping process with all 
  1728. locks on the table being held as is. A kill command will not be able to 
  1729. kill this process since an attention cannot be raised on a sleeping 
  1730. process. The only way to get around this problem is to make sure that 
  1731. users do not reboot their machines in the middle of a query.
  1732.  
  1733. Also if you are using Q+E you might want to change cancel = 1 your 
  1734. qex.ini / qe.ini depending on the version of Q+E. This will force a 
  1735. dbcancel to be issued when the query window is closed. If a dbcancel is 
  1736. not issued then a call to dbclose is made. Most often than not the 
  1737. connection is not closed properly since there is pending data on that 
  1738. socket.
  1739.  
  1740. One other option is to set the keepalive parameter on the server machine 
  1741. to a fairly low value if this is a configurable parameter on your 
  1742. platform. The result of setting this option is that at the specified 
  1743. time frame if there is no response from the client socket the server 
  1744. will drop that process. This will clear all the locks that are being 
  1745. held by that process.
  1746.  
  1747. ---------------------------------------------------
  1748. Question 3.7-11:  Does the server sort order affect performance? Is 
  1749. binary sort order the fastest way?
  1750.  
  1751. Answer:    Yes, binary sort order is fastest because no lookup is 
  1752. needed. Please keep in mind that sort order only has impact on 
  1753. operations that involve comparison of character data like creating 
  1754. indexes and evaluating qualifications on character values.
  1755.  
  1756. Sort orders are defined in .srt files found under in the character set 
  1757. directories. There are three values associated with each character. 
  1758. Looking at the character file defining the sort order, you can correlate 
  1759. those three values with the placement of that character in the file.
  1760.  
  1761. o    Primary sort value is determined by the line in the file.
  1762.  
  1763. o    Secondary sort value is determined by the position within the line.
  1764.  
  1765. o    Tertiary sort value is also dependent on the position of the character 
  1766. on the line.
  1767.  
  1768. Some examples from files in the iso_1 directory of a 4.9.1 installation:
  1769.  
  1770. dictionary.srt
  1771. ==============
  1772. char=0x41,0x61,0xC0,0xE0,0xC1,0xE1,0xC2,0xE2,0xC3,0xE3,0xC4,0xE4,0xC5,0xE5
  1773.  ;A, a, A-grave, a-grave, A-acute, a-acute, A-circumflex, a-circumflex,
  1774.  ;A-tilde, a-tilde, ;A-diaeresis, a-diaeresis, A-ring, a-ring
  1775.  
  1776. char = 0x42, 0x62 ;letter B, b
  1777.  
  1778. With dictionary sorting, every "a" is sorted before every "b" and among 
  1779. different "a" values there is sorting based on the different secondary 
  1780. sort values.
  1781.  
  1782.  
  1783. nocase.srt
  1784. ==========
  1785. char=0x41=0x61,0xC0=0xE0,0xC1=0xE1,0xC2=0xE2,0xC3=0xE3,0xC4=0xE4,0xC5=0xE5
  1786.  ;A, a, A-grave, a-grave, A-acute, a-acute, A-circumflex, a-circumflex,
  1787.  ;A-tilde, a-tilde, ;A-diaeresis, a-diaeresis, A-ring, a-ring
  1788.  
  1789. char = 0x42=0x62 ;letter B, b
  1790.  
  1791. With case insensitivity, "A" and "a" have the same secondary as well as 
  1792. primary sort order. That is denoted in the file by the equal sign 
  1793. between the two hex values for their encondings in the ISO 8859-1 
  1794. character set. The case insensitivity also applies to names in the SQL 
  1795. Server so you could not have two objects in the same database with names 
  1796. differing only in case, such as SuperBowl and SuperbOwl.
  1797.  
  1798. noaccent.srt
  1799. ============
  1800. char=0x41=0x61=0xC0=0xE0=0xC1=0xE1=0xC2=0xE2=0xC3=0xE3=0xC4=0xE4=0xC5=0xE5
  1801.  ;A, a, A-grave, a-grave, A-acute, a-acute, A-circumflex, a-circumflex,
  1802.  ;A-tilde, a-tilde, ;A-diaeresis, a-diaeresis, A-ring, a-ring
  1803.  
  1804. char = 0x42=0x62 ;letter B, b
  1805.  
  1806. With no accent, any "a" is equal to another. This could be useful if an 
  1807. application searches on last names and the entry is not exactly correct, 
  1808. like an A-grave instead of A-acute. This sort order is new with the 
  1809. 4.9.1. It is considered very useful by some European customers.
  1810.  
  1811. The only difference between the files nocase.srt and nocasepref.srt is 
  1812. the line "preference=true" in the latter. With preference, "A" is equal 
  1813. to "a". However, in the results of a query with ORDER BY on a character 
  1814. column, "A" will precede "a". This has important performance 
  1815. implications. An index on character data can not ensure values are 
  1816. already in the order you prefer and comparisons using tertiary sort 
  1817. values must be done in a worktable.
  1818.  
  1819. Robert Garvey robert@sybase.com {sun, lll-tis, pyramid, pacbell}!sybase!robert
  1820.  
  1821. ---------------------------------------------------
  1822. Question 3.7-12:  Does Sybase have a memory limit?
  1823.  
  1824. Answer:    Sybase has no memory limit. The typical problem with getting 
  1825. the memory you want on UNIX is due to the OS's insistence that there be 
  1826. enough swap space to accommodate the entire data space of a process at 
  1827. startup time.
  1828.  
  1829. UNIX doesn't want to give out memory it cannot in theory write 
  1830. *entirely* to disk at some point. Thus, when SQL Server asks for 16MB of 
  1831. memory, for example, unless you have that much swap space available, the 
  1832. request will be denied, and the server will live with less or abort. Run 
  1833. the utility your UNIX provides to tell how much swap is in use when you 
  1834. have this memory problem with SQL Server. If it varies a lot, consider 
  1835. putting your RUNSERVER command file in your system startup procedure, so 
  1836. SQL Server can start up when memory is most clear. If your swap space is 
  1837. often lacking in large amounts of space regardless of other system 
  1838. activity, you'll need to add more. The general rule is to have between 2 
  1839. and 3 times physical memory size in swap space.
  1840.  
  1841. Benjamin von Ullrich, Benjamin.von.Ullrich@sybase.com
  1842.  
  1843. ======================================================================
  1844.  
  1845. 3.8  Sybase Performance Tuning
  1846.  
  1847. ---------------------------------------------------
  1848. Question 3.8-1:  How much overhead do variable size and NULL columns 
  1849. require?
  1850.  
  1851. Answer:    The Sybase Performance and Tuning class notes give the 
  1852. following information:
  1853.  
  1854. An additional 5 bytes are used if there are ANY variable length fields.
  1855.  
  1856. An additional 1 byte is used for each variable length field.
  1857.  
  1858. Therefore, if you have two variable length fields, you have an extra 
  1859. seven bytes per row. Also, note that any field defined as allowing nulls 
  1860. is treated as variable length.
  1861.  
  1862. ---------------------------------------------------
  1863. Question 3.8-2:  How does the query optimizer work? Does the ordering of 
  1864. tables in the from clause or the conditionals in the where clauses 
  1865. affect the performance of the query?
  1866.  
  1867. Answer:    Normally, the ordering in the from clause and the where 
  1868. clause will not affect the performance of the query. The only time that 
  1869. it can have this effect is if there is more than one query plan that the 
  1870. optimizer estimates will take exactly the same time as the best plan. In 
  1871. this case, the optimizer will choose the first of these plans that it 
  1872. sees. The ordering in the from and where clauses will change which of 
  1873. these plans it sees first. Only in this case will the ordering affect 
  1874. the query plan.
  1875.  
  1876. This will affect the performance if some of these plans with identical 
  1877. cost estimates are significantly faster or slower than the others. This 
  1878. should not happen - the optimizer's cost estimates should reflect the 
  1879. true cost of running the query. But in practice, the optimizer sometimes 
  1880. has a bug or other problem that causes the cost estimates to be 
  1881. inaccurate.
  1882.  
  1883. So, for the ordering in the from or where clause to affect the 
  1884. performance, the following must be true:
  1885.  
  1886. - Two or more query plans have the same cost estimate, and this is 
  1887. the lowest cost estimate for the query.
  1888.  
  1889. - A bug in the optimizer causes one of these identical cost 
  1890. estimates to be significantly inaccurate.
  1891.  
  1892. Needless to say, these two things don't happen very often at the same 
  1893. time.
  1894.  
  1895. Jeff Lichtman at Sybase, jeffl@sybase.com
  1896.  
  1897. ---------------------------------------------------
  1898. Question 3.8-3:  Can I force the optimizer to access tables in a certain 
  1899. order or to use a particular index?
  1900.  
  1901. Answer:    Yes, if one of your problems is that tables are being 
  1902. accessed in the wrong order (the showplan is screwed up) then you can 
  1903. try the following:
  1904.  
  1905. set forceplan on
  1906.  
  1907. select . . .. 
  1908. from table_a a, table_b b, table_c c 
  1909. where . . .
  1910.  
  1911. set forceplan off
  1912.  
  1913. The 'set forceplan on/off' will tell the optimizer to access the tables 
  1914. in the order that they've been listed in the 'from' clause. Mind you, 
  1915. you have to make this determination as to which tables should come first 
  1916. in the list.
  1917.  
  1918. You can force the server to use a particular index by putting the index 
  1919. id ('indid' from sysindexes) in parentheses after the table name in the 
  1920. 'from' clause, but I recommend reconfiguring the query so that the 
  1921. optimizer can figure out which index to use on its own. Usually you can 
  1922. specify enough relationships to "nudge" the optimizer the right way.
  1923.  
  1924. Steve Medin had these comments on this topic:
  1925.  
  1926. Force index is implemented by placing a number after the table name in 
  1927. the from clause. The number refers tothe index that will be used by the 
  1928. optimizer, where the clustered index is always (1) and the nonclustered 
  1929. indices are sequenced in the order of your DDL create index statements, 
  1930. or chronologically if you have several scripts that build your indices. 
  1931. The possibility that a nonclustered index will get out of sequence is 
  1932. fairly high, but this feature can be quite useful if the optimizer 
  1933. refuses to use the clustered index on a table and you have provided 
  1934. where criteria for all the index columns. To force use of the clustered 
  1935. index on you ORDERS table, try:
  1936. ...
  1937.  
  1938. FROM ORDERS(1),
  1939. ...
  1940.  
  1941. This, again, can be useful when you can make an assumption about a 
  1942. table's size and you would rather tablescan a tiny table than get a 
  1943. clustered index iteration on the larger table that will not use the 
  1944. clustered index.
  1945.  
  1946. Try these out with showplan and stats io on. If you're really daring, 
  1947. try putting them in live application code. when you call tech support, 
  1948. they will tell you to remove the statements and recreate the problem 
  1949. before they will open a case.
  1950.  
  1951. ---------------------------------------------------
  1952. Question 3.8-4:  Does dropping an index cause recompilation of a stored 
  1953. procedure?
  1954.  
  1955. Answer:    Yes, dropping an index will cause recompilation of stored 
  1956. procedures which `touch' the indexed table. Adding an index, or updating 
  1957. statistics will NOT.
  1958.  
  1959. ---------------------------------------------------
  1960. Question 3.8-5:  Does the time for a select that yields 1000 rows from a 
  1961. table of 10,000 differ much from the same select when the table contains 
  1962. 100,000 rows?
  1963.  
  1964. Answer:    Table size would not be a factor iff you have a clustered 
  1965. index on the columns used to locate the SELECTed rows. Since clustering 
  1966. orders the rows by the columns which make up the index keys, we would 
  1967. locate the first data page where the key matches the qualification, and 
  1968. follow the page chain until the next key is encountered, and stop 
  1969. scanning. This all depends on the type of qualification, but this 
  1970. illustrates that a clustered index orders a table such that any part of 
  1971. it is just as locatable as any other, regardless of total size. B-trees 
  1972. properly maintained are never very deep, so index depth is never an 
  1973. issue in SQL Server.
  1974.  
  1975. Actually, you could also achieve like response time on a small vs. large 
  1976. table if the result columns of the query are covered by a nonclustered 
  1977. index. This is a poor way to accomplish this, however, since non-
  1978. clustered indexes on multi-million row tables take up a good deal of 
  1979. room, but this can be your only alternative if you are already using the 
  1980. clustered index for something else and can't change it.
  1981.  
  1982. Be careful not to add so much to the table if it is wide (has many 
  1983. fields, and/or many large character fields). Normalize out these "big 
  1984. text" fields to other table(s) that you only look at when you need to. 
  1985. some of the best performance gains can be had by having more rows per 
  1986. page.
  1987.  
  1988. Benjamin von Ullrich, Benjamin.von.Ullrich@sybase.com
  1989.  
  1990. ======================================================================
  1991.  
  1992. 3.9  Sybase Network Issues
  1993.  
  1994. ---------------------------------------------------
  1995. Question 3.9-1:  How can I make Sybase talk to two separate ethernet 
  1996. interfaces on our server?
  1997.  
  1998. Answer:     You can have as many master entries in the interfaces file 
  1999. for the protocol/port combinations that you have. Simply add a new line 
  2000. for the alternate hostname assigned to the second ethernet port, e.g.
  2001.  
  2002. The interfaces entry was:
  2003.  
  2004. SYBASE
  2005.  query tcp sun-ether primename 2025
  2006.  master tcp sun-ether primename 2025
  2007.  console tcp sun-ether primename 2026
  2008.  debug tcp sun-ether primename 2027
  2009.  
  2010. And it now is
  2011.  
  2012. SYBASE
  2013.  query tcp sun-ether primename 2025
  2014.  query tcp sun-ether secondname 2025
  2015.  master tcp sun-ether primename 2025
  2016.  master tcp sun-ether secondname 2025
  2017.  console tcp sun-ether primename 2026
  2018.  debug tcp sun-ether primename 2027
  2019.  
  2020. The key on the server end is the master line not the query line.
  2021.  
  2022. ---------------------------------------------------
  2023. Question 3.9-2:  Can I use Sybase over PPP (Peer-to-Peer protocol)?
  2024.  
  2025. Answer:    Yes. The PPP interface to your host is an extra interface 
  2026. with a new hostname. If you look in Sybase's interface file you'll see 
  2027. that you specify a hostname and a portnumber. This means that Sybase 
  2028. will listen to that particular portnumber on the interface that 
  2029. corresponds with the hostname specified in the interfaces file. This is 
  2030. probably your ethernet. Telnet and friends listen to ANYHOST, a special 
  2031. ip-address that translates to any interface that is up in the kernel.
  2032.  
  2033. The solution is simple and a bit Sybase version specific. First the 
  2034. hacks.
  2035.  
  2036. 1.  ANYHOST is implemented as ip address 0.0.0.0. If you add a host ALL 
  2037. to your hostfile and use ALL as hostname in the interfaces file, Sybase 
  2038. will pass 0.0.0.0 as ip address to the kernel and listens to its 
  2039. portnumber on all interfaces.
  2040.  
  2041. 2.  Some versions of Sybase appear to have the constant hostname 
  2042. NULLHOST built in. Principle the same as 1.
  2043.  
  2044. 3.  Now the proper solution. I don't know which version you need. 
  2045. Probably at least 4.8. May also be platform specific. But you can add 
  2046. more than one tcp line to the interfaces file (See previous Question). 
  2047. You can duplicate the line for "master" for each interface you want 
  2048. Sybase to listen to (that is duplicate with the appropriate hostname).
  2049.  
  2050. dave@exlog.com (Dave St.Clair)
  2051.  
  2052. ======================================================================
  2053.  
  2054. 4.0  Open Server
  2055.  
  2056. ======================================================================
  2057.  
  2058. 5.0  Open Client
  2059.  
  2060. ---------------------------------------------------
  2061. Question 5.0-1:  How can I use the Sybase Open Client with my C++ code?
  2062.  
  2063. Answer:    Create a header file like the following and you're all set.
  2064.  
  2065. #ifndef _FIX_SYBASE_H
  2066. #define _FIX_SYBASE_H
  2067. #define COMPILE_STYLE CPP_COMPILE
  2068.  
  2069. extern "C"
  2070. {
  2071. #include "sybfront.h"
  2072. #include "sybdb.h"
  2073. };
  2074. #endif /* ifndef _FIX_SYBASE_H */
  2075.  
  2076. ---------------------------------------------------
  2077. Question 5.0-2:  Which C compilers is the DOS version of the Open Client 
  2078. software compatible with?
  2079.  
  2080. Answer:    The Open Client was compiled using Microsoft C. The Borland 
  2081. C++ 3.1 compiler will not link properly with the Open Client.
  2082.  
  2083. ======================================================================
  2084.  
  2085. 6.0  APT 
  2086.  
  2087. ---------------------------------------------------
  2088. Question 6.0-1:  Is it possible to place other visible fields on top of 
  2089. invisible fields, or do I have to have big open spaces?
  2090.  
  2091. Answer:    A general guideline is to NOT have hidden fields at all. They 
  2092. clutter and generally confuse the form itself. According to some sources 
  2093. (I can't lay my hands on them t this time) hidden fields slow form 
  2094. processing and require more overhead than performing the same functions 
  2095. within an APT procedure. ANYTHING you can do with a hidden field you can 
  2096. do in your .fpl files.
  2097.  
  2098. ======================================================================
  2099.  
  2100. 7.0  DWB
  2101.  
  2102. ======================================================================
  2103.  
  2104. 8.0  Report Writer
  2105.  
  2106. ======================================================================
  2107.  
  2108. 9.0  Third Party Applications
  2109.  
  2110. ======================================================================
  2111.  
  2112. 9.1  User Interface Client Applications
  2113.  
  2114. 1.  APT
  2115.     Sybase, Inc.
  2116.     Comments:
  2117.  
  2118. 2.  Gain
  2119.     Sybase/Gain Technologies
  2120.     Comments:
  2121.  
  2122. 3.  Database WorkBench
  2123.     Sybase, Inc.
  2124.     Comments:
  2125.  
  2126. 4.  JYACC JAM/DBi
  2127.     JYACC, Inc.
  2128.     116 John Street 
  2129.     -or- One Sansome St., Suite 2100
  2130.     New York, NY 10038 San Francisco, CA 94104
  2131.     800-458-3313 415-951-1070
  2132.     Comments:
  2133.  
  2134. 5.  Uniface
  2135.     410-740-8745 -or- 510-748-6145
  2136.     Comments:
  2137.  
  2138. 6.  Power Builder (Microsoft Windows only)
  2139.     Powersoft Corporation
  2140.     70 Blanchard Road
  2141.     Burlington, MA 01803
  2142.     617-229-2200
  2143.     Comments:
  2144.  
  2145. 7.  Microsoft Access/Visual Basic
  2146.     Microsoft Corp.
  2147.     Comments:
  2148.     Windows 3.1
  2149.  
  2150. 8.  DataEase
  2151.     DataEase
  2152.     Comments:
  2153.  
  2154. 9.  Unify
  2155.     3901 Lennane Drive
  2156.     Sacramento, CA 95834-1922
  2157.     800-24-UNIFY
  2158.     Comments:
  2159.  
  2160. 10.  Focus
  2161.     Information Builders, Inc.
  2162.     1250 Broadway
  2163.     New York, NY
  2164.     212-736-4433
  2165.     Comments:
  2166.  
  2167. 11.  Q+E
  2168.     Pioneer Software
  2169.     Comments:
  2170.     Windows 3.1.
  2171.     Simple spreadsheet-like browser.
  2172.     Can be used as an OLE object.
  2173.  
  2174. 12.  Superbase
  2175.     SPC Software
  2176.     Comments:
  2177.     Windows 3.1
  2178.     Complete database forms/report/application package.
  2179.     SQL link purchased separately.
  2180.     Can be used as an OLE object.
  2181.  
  2182. ======================================================================
  2183.  
  2184. 9.2  Class Libraries
  2185.  
  2186. 1.  DBh++
  2187.     Rogue Wave
  2188.  
  2189. 2.  C++ API
  2190.     Qualix email at info@qualix.com
  2191.  
  2192. 3.  Persistence
  2193.     Persistence Software
  2194.  
  2195. ======================================================================
  2196.  
  2197. 9.3  Other Miscellaneous Products and Tools
  2198.  
  2199. 1.  SybPERL
  2200.  
  2201. 2.  SQL-BackTrack
  2202.     Qualix
  2203.  
  2204. 3.  dbViewer
  2205.     Qualix
  2206. -- 
  2207. +==============================+=============================================+
  2208. | David W. Pledger             | S T R A T E G I C   D A T A   S Y S T E M S |
  2209. | davidp@meaddata.com          |           PO Box 498, Springboro, OH  45066 |
  2210. | Custom Database Applications | Phone (513)748-2460, (800)253-5624 ext 2940 |
  2211. --
  2212. +==============================+=============================================+
  2213. | David W. Pledger             | S T R A T E G I C   D A T A   S Y S T E M S |
  2214. | davidp@meaddata.com          |           PO Box 498, Springboro, OH  45066 |
  2215. | Custom Database Applications | Phone (513)748-2460, (800)253-5624 ext 2940 |
  2216.