好文章,转。
https://www-10.lotus.com/ldd/ddwiki.nsf/dx/dblookup-troubleshooting.htm
Many factors must align to get a key-based lookup to work. If yours is not working, this document lists the things you should check. This is primarily about @DbLookup, but any key-based view lookup, such as NotesView.GetAllDocumentsByKey, has essentially the same set of possible issues. Some of these considerations apply to @DbColumn also (which doesn't use a key), so if you're having trouble with @DbColumn this document is also worth reading.
This is about Notes lookups; the functions @DbLookup and @DbColumn can also be used to read ODBC data or with custom drivers provided by an add-in library, but we don't cover that here -- this is only for where the class argument is "" or "Notes".
A separate section of this document covers the use of @DbLookup in XPage server-side JavaScript code. This function works somewhat differently from the formula language version.
Check Your Inputs
Frequently, developers will conclude a function is broken, when the problem really is that they have provided it the wrong input. As a first step, always check your inputs to make sure they have the value you thought they had. When working with formula language, a statement such as the following may be helpful (substitute your variable name for key):
@Prompt([Ok]; "Lookup key"; @If(@IsError(key); "ERROR: " + @Text(key); @IsText(key); """ + @Implode(key; "": "") + """; @Implode(@Text(key); ", ") ) ); result := @DbLookup(""; ""; "SomeView"; key; 2); ... |
I talked about the key here because it's the argument most often stored in a variable instead of hardcoded where you can see it in the code. But of course, any of the arguments could be wrong.
In addition, before you decide @DbLookup is returning the wrong value, open the view you're trying to look up to and see what data are really in it. It may be your documents or view column formula that's wrong. If the view is hidden, use Preview from Designer, or the menu View / (Ctrl+Shift) Go to... in the Notes client. If the key is a string, type the key value to activate the view quick search, and see whether you can find the row that way.
Entry not found in index
This is the most common error you will encounter, and in a way it's good news because it means that you located the server and the database and the view, and you do have access to them (though you might still have specified the wrong database or view, and that was why the key isn't found). The next sections detail several ways in which your key can be wrong, in addition to other things.
Basic Requirements for a Successful Lookup
To begin with, if you use the [FailSilent] option or have other code to trap and ignore an error result , take it out. The error text is valuable information for diagnosing the problem.
In case of failure, do a "sanity check" against this list to make sure the conditions for using this function exist. Error messages are indicative of the problem, but some errors may have more than one possible cause.
Other Things that Can Go Wrong
If you have specified the database with a replica ID, use the Domino Administrator tool to make sure there is not another database with the same replica ID on the server.
If the column is multivalued, but the column option to display multiple values in separate rows is not selected, you can only match the first value in a lookup.
In views with more than one categorized column, a lookup on the top-level category key will only return the documents from the first subcategory. E.g. if there's a category "Animals" containing "Dog" and "Horse", and you use "Animals" as your lookup key, you will only return values from documents in the "Dog" subcategory -- no "Horses". Instead, do your lookup to a different view that has only one level of categorization (or that is just sorted, not categorized).
In views with re-sort columns, @DbLookup will search the current sort order that the user has chosen for that view, rather than the default sorting. This is one reason it's generally considered a best practice to do your lookups against hidden views, even if they are near duplicates of views used by end users. There is not any way to predict, adjust, or detect what sort order the user has selected.
It's been reported that for a view column that's not sorted case and pitch sensitive, lookups of some non-ASCII strings will always fail. This needs further investigation. It probably applies to specific characters, and so may depend which language you're using. Meanwhile, if you run into this problem, make sure your view is sorted case and pitch sensitive and that the case and pitch of the key matches that in the column.
Sometimes you may get an error result from @DbLookup because the column you read data from contains an error value. If you look at the view you would see ERROR: displayed in the view. But of course, if this were the case, you would have noticed long before you got to this point, because the first thing you did was open the view, as we suggested up above. Right?
For @DbLookup, if your key is multivalued, the lookup will attempt to look up each key separately and combine the results into a single list, except that if the first key in the list is not found, the whole lookup fails even though other keys may be valid. If the first key succeeds, subsequent keys that fail will just be skipped. Of course, the requirement that all the results be of the same datatype still applies. If you have a list of keys and this style of processing doesn't suit you, using the @Transform function to look up the keys one at a time may be a good alternative.
If you're using @DbLookup to get the value of a rich text field or other non-summary field, and you're getting a blank value back, this may be caused by a view column with the same programmatic name as the rich text field. The view column will be used by preference, rather than looking into the document.
Tips for Performance / Effective Lookups
Developers often routinely use "NoCache", and often it's unnecessary. Using caching can significantly improve performance, particularly in forms used in the Notes client, where frequently there are several keyword lookups on the form which can delay loading if they all use NoCache. For an in-depth discussion of cache control and formula coding tips for best performance, see Performance basics for developers (whitepaper)
When you want to lookup to the current database, the correct second a rgument for @DbLookup and @DbColumn is "" -- not "" : "" (which takes a tiny bit longer to evaluate because it contains an operator) and definitely not @DbName (which wastes time reopening the database you already have open).
Example:
To lookup to another database on the same server whose path you know (presumably because it is the same on all servers), use, e.g.:
You may have been taught that it's more efficient to use a column number rather than a field name for the value to retrieve in @DbLookup. This is true on a first level, but the real story is a little more complex. Each column in the view has a field name (called the "programmatic name"). For formula columns, the programmatic name is automatically generated and looks like "$" followed by a number. For columns that refer just to a field, the programmatic name is the same as the field name. If @DbLookup field/column argument is a string, Notes will first try to match the name with the programmatic names of the columns, and if it finds a match, return data from that column. If there's not a matching name, it will look at the document for a field with the same name. This looking at a document is the part that's slow. So you can use a column programmatic name and that is still efficient, plus it's less likely to change than the column number. And if the programmatic name is the same as a field name, it looks like you're reading a field from the document -- but you're really not.
In Web Applications
There is no problem in using @DbLookup or the corresponding LotusScript or Java methods in a web-based application. There are differences because a Notes client-based application, where code is executing on the user's workstation, you have to specify the server name if the application is on a server. In a Domino web application, the code runs on the server, so to access a database on the same server, use the server name "", which means local.
Even if the same lookup that fails in a web application, works when the form is used in the Notes client, the failure is not because it's in a web application per se, but because of the differences in executing on a client vs. server. For instance, if the lookup specifies a server name, there may be DNS issues or an incorrect connection document on the server that prevents the target server from being found, or server trust settings or ACL considerations that block access to the data. The problem is not with the @DbLookup function, but with the different environment. It can be made to work.
On An XPage
The @DbLookup and @DbColumn functions on an XPage are somewhat different from the standard versions of these functions. The first argument, specifying 'class' and caching, is omitted (it's assumed to be "":"NoCache"). The values of the remaining arguments are used to construct a formula language expression to send to the formula engine for evaluation; this expression contains literals, since the formula engine does not know from your JavaScript variable names. E.g. if your JavaScript code says:
view = 'Reqs\by GLORB factor'; use \ when you mean
key = 'SuperGLORB';
column = 7;
db = new Array(@DbName()[0], 'reqLookups.nsf');
result = @DbLookup(db, view, key, column, '[FAILSILENT],[PARTIALMATCH]');
then the actual, exact macro language expression sent to the Session.evaluate method is @DbLookup("":"NoCache"; "":"reqLookups.nsf"; "Reqs\by GLORB factor"; "SuperGLORB"; 7; [FailSilent]:[PartialMatch]).
NOTE: Just as in formula language, is a special character in JavaScript string literals. To have a single in your string, you must use the sequence \, as above. Unlike formula language, if you forget to use \, the JavaScript edi tor will not strip out the single -- instead, it looks at the following characters to interpret it as a special character such as newline (n) or tab (t). So it may still look deceptively correct. This is only an issue if you hardcode the string. Strings read from elsewhere -- a field in a profile document, say -- contain the characters that are in them; they aren't scanned for escape sequences.
Some other points of difference between XPage and other formula lookups:
Given these limitations, all the information in the previous sections is still applicable to lookups from JavaScript server code on an XPage.
Appendix: Understanding Keyword Lookups
The attributes of lookups vis-a-vis case and pitch sensitivity deserve a little more in-depth treatment, so you can understand what's going on and maybe predict what will and will not work.
When you think of a view lookup, think of it as looking up information in a book where the pages are numbered alphabetically, one entry per page. A page in this scenario corresponds to a view row.
If someone hands you this book and asks you to find a particular entry, you might find it by conducting a binary search. If you've ever played the number-guessing game where someone picks a secret number, you make a guess, and they tell you "higher" or "lower", the process is similar. You open the book to the middle page, and decide whether the entry you're looking for comes before or after that point. Let's say it comes before. Then you open the first half of the book exactly in the middle (in other words, open the book 1/4 of the way from the front). You keep narrowing it down to a smaller and smaller range of pages, and looking at the page exactly in the middle of the range, until you either find the value you want, or find two consecutive pages that the value should appear between, and it doesn't (in which case you decide the value is not there).
Of course, this only works if you and the person who arranged the pages have the same idea about how to sort things alphabetically. If you assume that "chose" comes between "Chicago" and "Cooper", and the entries are sorted case-sensitive, you will fail to find "chose" even if it is there. There's no efficient way to do a case-insensitive search against data with a case-sensitive sort (remember, any character could be of a different case in the key and the matching entry).
Thanks to Nathan Freeman and Sean Jack for their contributions to this article.
如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!
赞0
添加新评论0 条评论